The following pseudo-code is taken from http://15418.courses.cs.cmu.edu/spring2013/article/46
while (1) {
n->next = p->next;
Node *old_next = p->next;
if (compare_and_swap(&p->next, old_next, n) == old_next)
return;
}
This is the push operation for a lock-free stack that uses the compare and swap idiom, but does it atomically. It does not seem an ABA issue is relevant here, and I am wondering if that's generally the case for push and insertion operations?
You are right that this function does not suffer from the ABA problem, because there is nothing that depends on the
old_nextvalue before the call tocompare_and_swap.Consider the (simplified) pop operation:
Here we load
s->topintotopand later perform a CAS ons->topwithtopas expected value. But before the CAS, we readtop->next, so we perform an operation that depends ontop! This is what causes the ABA problem.It is not possible to generally state that all push/insert operations are free of the ABA problem, since it depends on more details. As a somewhat contrived example, consider a push operation that conditionally pushes the value only if it is greater.
This also suffers from the ABA problem, because it might break our invariant that the values are strictly ordered.