Aba Problem

2
ABA PROBLEM: In Comparison of Locked and Lockless Code for Fetch-and-op there is a time interval between when a thread executes”x_old = x”and when the thread executes InterlockedCompareExchange. During this interval, other processors might perform other fetchand-op operations. For example, suppose the initial value read is A. An intervening sequence of fetch-and-op operations by other processorsmight change x to B and then back to A. When the original thread executes InterlockedCompareExchange, it will be as if the other processor's actions never happened. As long as the order in which op isexecuted does not matter, there is no problem. The net result is the same as if the fetch-and-op operations were reordered such that the intervening sequence happens before the first read. But sometimes fetch-and-op has uses where changing x from A to B to A does make a difference. The problem is indeed known as the ABA problem. Lockless Implementation of a Linked Stack that May Suffer from ABA Problem Node* Top; // Pointer to top item on stack. void BrokenLocklessPush( Node* node ) { Item *t_old, t_was; do { Item* t_old = Top; n->next = t_old; t_was = InterlockedCompareExchange(&Top,node,t_old); } while( t_was!=t_old ); } Item* BrokenLocklessPop() { Item *t_old, *t_was, *t_new; do { t_old = Top; t_new = t_old->next; // ABA problem may strike below! t_was = InterlockedCompareExchange(&Top,t_new,t_old); } while( t_was!=t_old ); return t_old; }

description

ABA PROBLEM

Transcript of Aba Problem

ABA PROBLEM:

In Comparison of Locked and Lockless Code for Fetch-and-op there is a time interval between when a thread executesx_old = xand when the thread executes InterlockedCompareExchange.

During this interval, other processors might perform other fetchand-op operations.

For example, suppose the initial value read is A. An intervening sequence of fetch-and-op operations by other processorsmight change x to B and then back to A.

When the original thread executes InterlockedCompareExchange, it will be as if the other processor's actions never happened. As long as the order in which op isexecuted does not matter, there is no problem.

The net result is the same as if the fetch-and-op operations were reordered such that the intervening sequence happens before the first read.

But sometimes fetch-and-op has uses where changing x from A to B to A does make a difference. The problem is indeed known as the ABA problem.

Lockless Implementation of a Linked Stack that May Suffer from ABA ProblemNode* Top; // Pointer to top item on stack.

void BrokenLocklessPush( Node* node ) {

Item *t_old, t_was;

do {

Item* t_old = Top;

n->next = t_old;

t_was = InterlockedCompareExchange(&Top,node,t_old);

} while( t_was!=t_old );

}

Item* BrokenLocklessPop() {

Item *t_old, *t_was, *t_new;

do {

t_old = Top;

t_new = t_old->next;

// ABA problem may strike below!

t_was = InterlockedCompareExchange(&Top,t_new,t_old);

} while( t_was!=t_old );

return t_old;

}

Sequence Illustrates ABAProblem for Code

The solution to the ABA problem is to never reuse A. In a garbagecollected environment such as Java or .NET, this is simply a matter of not recycling nodes.

That is, once a node has been popped, never push it again. Instead allocate a fresh node. The garbage collector will do the hard work of checking that the memory for node A is not recycled until all extant references to it are gone.

In languages with garbage collection, the problem is harder. An old technique dating back to the IBM 370 changes ABA to ABA. In other words, make A slightly different each time.

Another solution is to build a miniature garbage collector that handles pointers involved in compare-exchange operations. These pointers are called ha za rd pointers, because they present a hazard to lockless algorithms.