In some forums and books (i.e. C++ Concurrency in Action) there's a nice example of multi-producer/multi-consumer stack, and in pop implementations they usually do the following:
// head is an std::atomic<node*> variable
node *old_head = head.load();
while(old_head && !head.compare_exchange_weak(old_head, old_head->next));
...
Why would using a std::atomic<T>::compare_exchange_* prevent the ABA issue?ABA related issue would then happen.
I believe I'm missing something. What am I missing here?
Cheers
Yes, you would suffer from an ABA problem here.
Though, I think that wouldn't matter because the implementation you are referring to(listing 7.3 in CiA) is anyway invalid, it is leaking nodes.
If we have a look at the most simple reference-counted implementation, the one using a lock-free std::shared_ptr
(listing 7.9 in CiA) we see that the problem wouldn't happen. When using shared pointers, the old_head would not be deleted as our thread still holds a reference to it, as such a newly created head couldn't be created in the memory address of the old head.
There is also a thread on the official Concurrency in Action Manning forums about ABA problems in the stack implementation.