// spinlockAcquireRelease.cpp
#include <atomic>
#include <thread>
class Spinlock{
std::atomic_flag flag;
public:
Spinlock(): flag(ATOMIC_FLAG_INIT) {}
void lock(){
while(flag.test_and_set(std::memory_order_acquire) ); // line 12
}
void unlock(){
flag.clear(std::memory_order_release);
}
};
Spinlock spin;
void workOnResource(){
spin.lock();
// shared resource
spin.unlock();
}
int main(){
std::thread t(workOnResource);
std::thread t2(workOnResource);
t.join();
t2.join();
}
In the notes, it is said:
In case more than two threads use the spinlock, the acquire semantic of the lock method is not sufficient. Now the lock method is an acquire-release operation. So the memory model in line 12 [the call to
flag.test_and_set(std::memory_order_acquire)
] has to be changed tostd::memory_order_acq_rel
.
Why does this spinlock work with 2 threads but not with more than 2? What is an example code that cause this spinlock to become wrong?
Source: https://www.modernescpp.com/index.php/acquire-release-semantic