2017-08-18 22:55:31 +08:00
|
|
|
#pragma once
|
|
|
|
#include "../acl_cpp_define.hpp"
|
|
|
|
|
|
|
|
namespace acl
|
|
|
|
{
|
|
|
|
|
|
|
|
template<typename T>
|
|
|
|
class atomic
|
|
|
|
{
|
|
|
|
public:
|
2017-09-01 23:14:20 +08:00
|
|
|
atomic(T* t)
|
|
|
|
{
|
2017-09-02 09:42:11 +08:00
|
|
|
atomic_ = atomic_new();
|
|
|
|
atomic_set(atomic_, t);
|
2017-09-01 23:14:20 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
virtual ~atomic(void)
|
|
|
|
{
|
2017-09-02 09:42:11 +08:00
|
|
|
atomic_free(atomic_);
|
2017-09-01 23:14:20 +08:00
|
|
|
}
|
2017-08-18 22:55:31 +08:00
|
|
|
|
2017-09-01 23:14:20 +08:00
|
|
|
T* cas(T* cmp, T* val)
|
|
|
|
{
|
2017-09-02 09:42:11 +08:00
|
|
|
return (T*) atomic_cas(atomic_, cmp, val);
|
2017-09-01 23:14:20 +08:00
|
|
|
}
|
2017-08-18 22:55:31 +08:00
|
|
|
|
2017-09-01 23:14:20 +08:00
|
|
|
T* xchg(T* val)
|
|
|
|
{
|
2017-09-02 09:42:11 +08:00
|
|
|
return (T*) atomic_xchg(atomic_, val);
|
2017-09-01 23:14:20 +08:00
|
|
|
}
|
2017-08-18 22:55:31 +08:00
|
|
|
|
|
|
|
protected:
|
2017-09-02 09:42:11 +08:00
|
|
|
void* atomic_;
|
2017-08-18 22:55:31 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
class atomic_long : public atomic<long long>
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
atomic_long(long long n = 0);
|
|
|
|
|
|
|
|
~atomic_long(void) {}
|
|
|
|
|
|
|
|
void set(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)
|
|
|
|
{
|
|
|
|
return n_;
|
|
|
|
}
|
|
|
|
|
|
|
|
void operator=(long long n)
|
|
|
|
{
|
|
|
|
set(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_;
|
|
|
|
};
|
|
|
|
|
2017-09-02 09:42:11 +08:00
|
|
|
// 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*);
|
|
|
|
|
2017-08-31 17:52:18 +08:00
|
|
|
#include "thread.hpp"
|
|
|
|
|
2017-08-18 22:55:31 +08:00
|
|
|
class atomic_long_test
|
|
|
|
{
|
2017-08-31 17:52:18 +08:00
|
|
|
private:
|
|
|
|
atomic_long count_;
|
2017-08-18 22:55:31 +08:00
|
|
|
public:
|
|
|
|
atomic_long_test(void) {}
|
|
|
|
~atomic_long_test(void) {}
|
|
|
|
|
|
|
|
void run(void)
|
|
|
|
{
|
2017-08-31 17:52:18 +08:00
|
|
|
|
|
|
|
long long n = count_++;
|
2017-08-18 22:55:31 +08:00
|
|
|
printf(">>n=%lld\r\n", n);
|
|
|
|
|
2017-08-31 17:52:18 +08:00
|
|
|
n = count_;
|
2017-08-18 22:55:31 +08:00
|
|
|
printf(">>n=%lld\r\n", n);
|
|
|
|
|
2017-08-31 17:52:18 +08:00
|
|
|
n = ++count_;
|
2017-08-18 22:55:31 +08:00
|
|
|
printf(">>n=%lld\r\n", n);
|
|
|
|
|
2017-08-31 17:52:18 +08:00
|
|
|
n = --count_;
|
2017-08-18 22:55:31 +08:00
|
|
|
printf(">>n=%lld\r\n", n);
|
|
|
|
|
2017-08-31 17:52:18 +08:00
|
|
|
n = count_--;
|
2017-08-18 22:55:31 +08:00
|
|
|
printf(">>n=%lld\r\n", n);
|
|
|
|
|
2017-08-31 17:52:18 +08:00
|
|
|
n = count_;
|
2017-08-18 22:55:31 +08:00
|
|
|
printf(">>n=%lld\r\n", n);
|
|
|
|
|
2017-08-31 17:52:18 +08:00
|
|
|
count_ -= 1;
|
|
|
|
n = count_;
|
2017-08-18 22:55:31 +08:00
|
|
|
printf(">>n=%lld\r\n", n);
|
|
|
|
|
2017-08-31 17:52:18 +08:00
|
|
|
printf(">>count > 1 ? %s\r\n", count_ >= 1 ? "yes" : "no");
|
|
|
|
printf(">>1 > count ? %s\r\n", 1 > count_ ? "yes" : "no");
|
2017-08-18 22:55:31 +08:00
|
|
|
|
|
|
|
int i = 1;
|
2017-08-31 17:52:18 +08:00
|
|
|
count_ = i;
|
|
|
|
n = count_;
|
2017-08-18 22:55:31 +08:00
|
|
|
printf(">>n=%lld\r\n", n);
|
|
|
|
}
|
2017-08-31 17:52:18 +08:00
|
|
|
|
2017-09-02 09:42:11 +08:00
|
|
|
class mythread : public thread
|
2017-08-31 17:52:18 +08:00
|
|
|
{
|
2017-09-02 09:42:11 +08:00
|
|
|
public:
|
|
|
|
mythread(atomic_long_test& at) : at_(at) {}
|
|
|
|
~mythread(void) {}
|
|
|
|
protected:
|
|
|
|
void* run(void)
|
2017-08-31 17:52:18 +08:00
|
|
|
{
|
2017-09-02 09:42:11 +08:00
|
|
|
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);
|
2017-08-31 17:52:18 +08:00
|
|
|
thr1.set_detachable(false);
|
|
|
|
thr2.set_detachable(false);
|
|
|
|
thr3.set_detachable(false);
|
|
|
|
thr1.start();
|
|
|
|
thr2.start();
|
|
|
|
thr3.start();
|
|
|
|
thr1.wait();
|
|
|
|
thr2.wait();
|
|
|
|
thr3.wait();
|
|
|
|
}
|
2017-08-18 22:55:31 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace acl
|