Consider this code (from 'C++ concurrency in action' [Second edition]: page 212):
void LockFreeStack::pop (stack_data& result)
{
Node* old_head = head.load();
while(!head.compare_exchange_weak(old_head, old_head->next))
;
result = old_head->data;
}
I think it's possible to thread-one execute pop()
and after executing first line (loading head
) time slicing happened to thread-two, which is executing push(T&)
. So now value of head
atomic variable is not equal to old_head
and while
-loop won't break.
It's right ?
assuming
head
is astd::atomic<Node*>
then the code is correct as whencompare_exchange_weak
fails it loads the current value of the variable into its first parameter, after thecompare_exchange_weak
callold_head
will always contain the current value ofhead
.The code is roughly equivalent to doing the following without atomics:
Concurrent calls to
pop
are therefore safe and shouldn't block forever (other than due to other threads constantly calling pop and somehow always setting the value before the current thread gets a chance).