Questions about spinlock mutex implementation via std::atomic_flag

62 views Asked by At

I'm currently reading a book called C++ concurrency in action. There is an example of spinlock mutex impl:

class spinlock_mutex
{
 std::atomic_flag flag;
public:
 spinlock_mutex():
 flag(ATOMIC_FLAG_INIT)
 {}
 void lock()
 {
   while(flag.test_and_set(std::memory_order_acquire));
 }
 void unlock()
 {
   flag.clear(std::memory_order_release);
 }
};

The first problem I faced in this sample is that operator= is deleted for std::atomic_flag and it doesn't compile. But if I remove ctor, and just make this instruction in private class section, everything is fine, no errors: std::atomic_flag flag = ATOMIC_FLAG_INIT Why does it compile? Isn't it the same operator= used here?

The 2nd one thing I would like to ask is, how actually does looping process goes?

If I create:

spinlock_mutex mtx;
mtx.lock();

//some code

mtx.unlock();

And try to print some debug inside method's lock while-loop:

void lock()
{
  while (flag.test_and_set(std::memory_order_acquire)) {
    std::cout << "here" << "\n";
  }
}

it doesn't print anything, so it looks like it doesn't get inside, how do we achive looping then?

I've described 2 problems and what I've tried above.

1

There are 1 answers

0
Jan Schultke On
  1. It sounds like you're mistaking operator= for copy-initialization. std::atomic_flag::operator= is deleted indeed, but std::atomic_flag flag = ATOMIC_FLAG_INIT does not use the assignment operator. It uses the constructor of the flag.

  2. It's not going to print anything if the mutex is initially unlocked, i.e. if flag is unset. You need some contention, i.e. you need two separate threads that try to lock the mutex at the same time. If it doesn't enter the while loop, that means that it locked successfully without any waiting.