20 #ifndef GALOIS_SUBSTRATE_PTRLOCK_H
21 #define GALOIS_SUBSTRATE_PTRLOCK_H
27 #include "galois/config.h"
34 void ptr_slow_lock(std::atomic<uintptr_t>& l);
43 std::atomic<uintptr_t> _lock;
50 PtrLock(
const PtrLock& p) : _lock(p._lock.load(std::memory_order_relaxed)) {}
56 _lock.store(p._lock.load(std::memory_order_relaxed),
57 std::memory_order_relaxed);
62 uintptr_t oldval = _lock.load(std::memory_order_relaxed);
65 if (!_lock.compare_exchange_weak(oldval, oldval | 1,
66 std::memory_order_acq_rel,
67 std::memory_order_relaxed))
73 internal::ptr_slow_lock(_lock);
78 _lock.store(_lock.load(std::memory_order_relaxed) & ~(uintptr_t)1,
79 std::memory_order_release);
84 _lock.store(0, std::memory_order_release);
89 assert(!((uintptr_t)val & 1));
90 _lock.store((uintptr_t)val, std::memory_order_release);
94 return (T*)(_lock.load(std::memory_order_relaxed) & ~(uintptr_t)1);
98 uintptr_t nval = (uintptr_t)val;
101 _lock.store(nval, std::memory_order_relaxed);
105 uintptr_t oldval = _lock.load(std::memory_order_relaxed);
106 if ((oldval & 1) != 0)
108 oldval = _lock.fetch_or(1, std::memory_order_acq_rel);
109 return !(oldval & 1);
113 return _lock.load(std::memory_order_acquire) & 1;
118 inline bool CAS(T* oldval, T* newval) {
119 assert(!((uintptr_t)oldval & 1) && !((uintptr_t)newval & 1));
120 uintptr_t old = (uintptr_t)oldval;
121 return _lock.compare_exchange_strong(old, (uintptr_t)newval);
127 uintptr_t old = 1 | (uintptr_t)oldval;
128 return _lock.compare_exchange_strong(old, 1 | (uintptr_t)newval);
132 template <
typename T>
147 inline bool CAS(T* oldval, T* newval) {
148 if (_lock == oldval) {
PtrLock & operator=(const PtrLock &p)
Definition: PtrLock.h:52
bool CAS(T *oldval, T *newval)
Definition: PtrLock.h:147
PtrLock is a spinlock and a pointer.
Definition: PtrLock.h:42
T * getValue() const
Definition: PtrLock.h:93
void setValue(T *val)
Definition: PtrLock.h:144
void unlock_and_clear()
Definition: PtrLock.h:141
constexpr PtrLock()
Definition: PtrLock.h:48
void unlock_and_set(T *val)
Definition: PtrLock.h:87
bool CAS(T *oldval, T *newval)
CAS only works on unlocked values the lock bit will prevent a successful cas.
Definition: PtrLock.h:118
void setValue(T *val)
Definition: PtrLock.h:97
DummyPtrLock()
Definition: PtrLock.h:137
bool stealing_CAS(T *oldval, T *newval)
CAS that works on locked values; this can be very dangerous when used incorrectly.
Definition: PtrLock.h:126
void lock()
Definition: PtrLock.h:139
T * getValue() const
Definition: PtrLock.h:143
void unlock_and_clear()
Definition: PtrLock.h:82
bool is_locked() const
Definition: PtrLock.h:112
void lock()
Definition: PtrLock.h:61
void unlock()
Definition: PtrLock.h:76
bool is_locked() const
Definition: PtrLock.h:146
Definition: PtrLock.h:133
void unlock_and_set(T *val)
Definition: PtrLock.h:142
PtrLock(const PtrLock &p)
Definition: PtrLock.h:50
bool try_lock()
Definition: PtrLock.h:104
void unlock()
Definition: PtrLock.h:140
bool stealing_CAS(T *oldval, T *newval)
Definition: PtrLock.h:154
bool try_lock() const
Definition: PtrLock.h:145