#pragma once #include "../acl_cpp_define.hpp" namespace acl { // internal functions being used void* atomic_new(void); void atomic_free(void*); void atomic_set(void*, void*); void* atomic_cas(void*, void*, void*); void* atomic_xchg(void*, void*); template class atomic { public: atomic(T* t) { atomic_ = atomic_new(); atomic_set(atomic_, t); } virtual ~atomic(void) { atomic_free(atomic_); } T* cas(T* cmp, T* val) { return (T*) atomic_cas(atomic_, cmp, val); } T* xchg(T* val) { return (T*) atomic_xchg(atomic_, val); } protected: void* atomic_; private: atomic(const atomic&); }; class ACL_CPP_API atomic_long : public atomic { public: atomic_long(long long n = 0); atomic_long(const atomic_long& n); ~atomic_long(void) {} void set(long long n); long long cas(long long cmp, long long n); long long fetch_add(long long n); long long add_fetch(long long n); operator long long() const { return n_; } long long value(void) const { return n_; } void operator=(long long n) { set(n); } void operator=(const atomic_long& n) { set(n.n_); } long long operator++() { return add_fetch(1); } long long operator++(int) { return fetch_add(1); } long long operator--() { return add_fetch(-1); } long long operator--(int) { return fetch_add(-1); } long long operator+=(long long n) { return add_fetch(n); } long long operator+=(int n) { return add_fetch(n); } long long operator-=(long long n) { return add_fetch(-n); } long long operator-=(int n) { return add_fetch(-n); } private: long long n_; }; #include "thread.hpp" class atomic_long_test { private: atomic_long count_; public: atomic_long_test(void) {} ~atomic_long_test(void) {} void run(void) { long long n = count_++; printf(">>n=%lld\r\n", n); n = count_; printf(">>n=%lld\r\n", n); n = ++count_; printf(">>n=%lld\r\n", n); n = --count_; printf(">>n=%lld\r\n", n); n = count_--; printf(">>n=%lld\r\n", n); n = count_; printf(">>n=%lld\r\n", n); count_ -= 1; n = count_; printf(">>n=%lld\r\n", n); printf(">>count > 1 ? %s\r\n", count_ >= 1 ? "yes" : "no"); printf(">>1 > count ? %s\r\n", 1 > count_ ? "yes" : "no"); int i = 1; count_ = i; n = count_; printf(">>n=%lld\r\n", n); } class mythread : public thread { public: mythread(atomic_long_test& at) : at_(at) {} ~mythread(void) {} protected: void* run(void) { for (size_t i = 0; i < 100; i++) at_.run(); return NULL; } private: atomic_long_test& at_; }; static void test(void) { atomic_long_test at; mythread thr1(at), thr2(at), thr3(at); thr1.set_detachable(false); thr2.set_detachable(false); thr3.set_detachable(false); thr1.start(); thr2.start(); thr3.start(); thr1.wait(); thr2.wait(); thr3.wait(); } }; } // namespace acl