Javaを模したAtomicMarkableReferenceのAtomicMarkablePointer(C++)
8950 ワード
1 //@author: Zou Xiaohang
2 //@describe: this class is like AtomicMarkableReference which is in java concurrent package.
3 // remember the pointer is 32bits address
4 template<class Pointer>
5 class AtomicMarkablePointer{
6 private:
7 std::atomic<Pointer> ptr;
8 const int32_t Marked = 0x00000001;
9 const int32_t UnMraked = 0x00000000;
10 public:
11 explicit AtomicMarkablePointer(Pointer p, bool mark){
12 ptr.store((Pointer)((int32_t)p | (int32_t)mark));
13 }
14 AtomicMarkablePointer(const AtomicMarkablePointer &a){
15 ptr.store(a.ptr.load());
16 }
17 AtomicMarkablePointer operator = (const AtomicMarkablePointer &a){
18 if (*this != a){
19 ptr.store(a.ptr.load());
20 }
21 return *this;
22 }
23 Pointer getReference() const {
24 Pointer p = ptr.load();
25 return (bool)((int32_t)p & Marked) ? (Pointer)((int32_t)(p)& ~Marked) : p;
26 }
27 bool isMarked() const {
28 Pointer p = ptr.load();
29 return (bool)((int32_t)p & Marked);
30 }
31 Pointer get(bool &b) const {
32 Pointer p = ptr.load();
33 b = (bool)((int32_t)p & Marked);
34 return b ? (Pointer)((int32_t)(p)& ~Marked) : p;
35 }
36 bool compareAndSet(Pointer expectedPointer, Pointer newPointer,
37 bool expectedMark, bool newMark){
38 Pointer p = ptr.load();
39 bool b = (bool)((int32_t)p & Marked);
40 if (b == expectedMark){
41 expectedPointer = (Pointer)((int32_t)expectedPointer | (int32_t)b);
42 return ptr.compare_exchange_strong(expectedPointer, (Pointer)((int32_t)newPointer | (int32_t)newMark));
43 }
44 return false;
45 }
46 void set(Pointer newPointer, bool newMark){
47 newPointer = (Pointer)((int32_t)newPointer | (int32_t)newMark);
48 ptr.exchange(newPointer);
49 }
50 bool attemptMark(Pointer expectedPointer, bool newMark){
51 Pointer newPointer = (Pointer)((int32_t)expectedPointer | (int32_t)newMark);
52 expectedPointer = isMarked() ? (Pointer)((int32_t)expectedPointer | Marked) : expectedPointer;
53 return ptr.compare_exchange_strong(expectedPointer, newPointer);
54 }
55 /*void print()const{
56 std::cout << getReference() << " ";
57 std::cout << (isMarked() ? "Marked" : "UnMarked");
58 }*/
59 };