3

Typical way of implementing lock-free data structures is using atomic CAS operations, such as std::compare_exchange_strong or std::compare_exchange_weak. The example of this technique's usage can be seen in Antony Williams' "C++ Concurrency in Action", where a lock-free stack is implemented. The stack is implemented as a linked list with std::atomic<node*> head pointer. CAS operations are performed on this pointer during pushs and pops. But C++ standard guarantees that only std::atomic_flag is lock-free, other atomic types, including std::atomic<T*>, may be not lock-free.

1) do I understand correctly that if std::atomic<T*> is not lock-free (std::atomic::is_lock_free() returns false), then data structure based on CAS operations on std::atomic<T*> is not lock-free?

2) If yes, then, what are alternative ways to implement lock-free data structures on C++ if std::atomic_flag is the only lock-free atomic type for some compiler?

3
  • 1
    Is it a huge problem for you in real life if some operations are not lock-free? Have you benchmarked your application and determined that the "non-lock-free-ness" is causing an actual performance problem? If not, why do you care? Commented Jun 12, 2018 at 20:19
  • @JesperJuhl The question is just out of curiosity, currently I'm not aware of the platform with non-lock-free std::atomic<void*> type. Commented Jun 12, 2018 at 20:20
  • atomic_flag is not generally recommended unless your use-case is so simple that you only need the limited operations it provides. Related: Why does C/C++ not have a atomic flag test_and_clear? Commented Mar 14, 2024 at 3:25

1 Answer 1

5

The only likely reason for a compiler not to have a lock free implementation of an atomic type is if the processor doesn't have atomic operations. I'm not aware of a modern processor where this is the case.

If the processor doesn't support atomic operations you probably have no choice but to use mutexes, semaphores or similar synchronisation primitives

Sign up to request clarification or add additional context in comments.

2 Comments

Well, strictly speaking, a compiler does have one lock-free implementation: for std::atomic_flag. The question is what if it is the only lock-free implementation. Or do you mean that all modern processors are likely to have atomic operations for data that fits into a single word (void*, for example)?
I'm no expert on the availability of cpu instructions but I'd be very surprised if any cpu capable of multi threading didn't have the requisite atomic operations for words

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.