Reputation:
Is this code threadsafe? Should I have volatile in the function sig? (ex: void Unlock() volatile {v=0;}
) If it isn't how do i make this threadsafe?
class SimpleLock {
std::atomic<int> v;
public:
bool try_lock() { int z=0; return v.compare_exchange_strong(z, 1); }
void lock() { while(try_lock()==false) std::this_thread::yield(); }
void unlock() {v=0;}
};
Upvotes: 7
Views: 1805
Reputation: 62469
Yes, it is thread-safe, although you could rename Lock
to TryLock
since you are not calling CAS in a loop until it succeeds. Traditionally Lock
operations are supposed to block until the acquire succeeds.
Regarding volatile
, the docs of std::atomic
specify (about the =
operator):
Atomically assigns a value t to the atomic variable. Equivalent to store(desired).
Then about store
:
void store( T desired, memory_order = std::memory_order_seq_cst );
Then about memory_order = std::memory_order_seq_cst
:
So no, you don't need volatile
here. Additionally, volatile
has weaker guarantees than the ones above (in fact, volatile
is mostly useless in C++):
Within a thread of execution, accesses (reads and writes) to all volatile objects are guaranteed to not be reordered relative to each other, but this order is not guaranteed to be observed by another thread, since volatile access does not establish inter-thread synchronization.
Upvotes: 8