仿Java的AtomicMarkableReference的AtomicMarkablePointer(C++)
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 };