4

Since std::lock_guard doesn't work with std::atomic_flag I've implemented my own version:

class atomic_guard { public: inline atomic_guard(std::atomic_flag& lock) : lock(lock) { while (this->lock.test_and_set()) { /* spin */ }; }; inline ~atomic_guard() { this->lock.clear(); }; private: std::atomic_flag& lock; }; 

This seems to work fine. The question is: is this a correct way to implement RAII for std::atomic_flag? Also is there a built-in guard for that? If not, why? The specialization std::lock_guard<std::atomic_flag> looks like something very natural.

1 Answer 1

5

Your use of atomic_guard as a standalone mutex lookalike is correct, if slightly unusual.

Using std::atomic_flag directly with std::lock_guard is not possible because the std::lock_guard template manages a mutex while std::atomic_flag is a (low-level) atomic boolean type.

A mutex implementation that can be used with std::lock_guard has to provide member functions lock and unlock and can be implemented like this:

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

Note that this is a very basic and inefficient mutex implementation, but it is compatible with std::lock_guard:

my_mutex mtx; std::lock_guard<my_mutex> lck{mtx}; 
Sign up to request clarification or add additional context in comments.

5 Comments

What do you mean by inefficient? Isn't atomic_flag more efficient then standard mutex? At least for some cases, e.g. when the locking time is supposed to be short.
@freakish If a thread is waiting to acquire the lock using my_mutex, it is wasting a lot of CPU time since it is in a busy while loop
I wouldn't call that "wasting". You gain execution time, so its a tradeof. It seems that atomic_flag can be even ~50x faster then standard mutex. So if you lock for a short period then "wasting" these cpu cycles might be worth it. Here's the benchmark: arangodb.com/2015/02/comparing-atomic-mutex-rwlocks Of course I will do proper tests in my scenario, but I do expect at least 2x speedup.
But I do like your my_mutex implementation. I didn't know that you can use std::lock_guard with a custom class (and that it is so easy). That's very nice.
@freakish I have done some performance comparison with a std::mutex (easy to replace in lock_guard).. Usually the standard library mutex wins. Obviously that implementation is more advanced. I believe it also loops for a short time before a context switch is performed

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.