In multithread computing, the problem ABA occurs during synchronization, when the location is read twice, has the same value for both readings, and "value is the same" is used to indicate "nothing has changed". However, another thread can execute between two reads and change the value, do another job, then change the return value, thus fooling the first thread into thinking "nothing changes" even though the second thread does the job that violates that assumption.
Masalah ABA terjadi ketika beberapa utas (atau proses) mengakses interleave data bersama. Di bawah ini adalah urutan kejadian yang akan menghasilkan masalah ABA:
- Proses membaca nilai A dari memori bersama,
- diutamakan, memungkinkan proses untuk menjalankan,
- memodifikasi nilai memori bersama A ke nilai B dan kembali ke A sebelum preemption,
- memulai eksekusi lagi, melihat bahwa nilai memori bersama tidak berubah dan berlanjut.
Meskipun dapat terus dieksekusi, mungkin saja perilaku tersebut tidak akan benar karena modifikasi "tersembunyi" dalam memori bersama.
A common case of ABA problems is found when implementing a free-lock data structure. If an item is removed from the list, deleted, and then new items are allocated and added to the list, it is common for the allocated object to be in the same location as the deleted object because of the optimization. The pointer to the new item is thus sometimes the same as the pointer to the old item which is an ABA issue.
Video ABA problem
Example
Consider the ABA software example using a lock-free stack:
This code can usually prevent problems from concurrent access, but suffers from ABA issues. Consider the following sequence:
The stack initially contains over -> A -> B -> C
Thread 1 starts running pop:
ret = A; Ã next = B;
Thread 1 terpotong tepat sebelum compare_exchange_weak ...
Now the stack is over -> A -> C
Ketika Thread 1 melanjutkan:
compare_exchange_weak (A, B)
This instruction works because it finds top == ret (both A), so set the top to next (the B). Because B has been deleted, the program will access the freed memory when trying to see the first element on the stack. In C, as shown here, accessing the freed memory is undefined behavior: this can cause crashes, data corruption or even just silently seems to function correctly. Such ABA bugs can be difficult to debug.
Maps ABA problem
Workarounds
Country reference tagged
The general solution is to add additional "tag" or "cap" bits to the quantity under consideration. For example, an algorithm using comparison and swap on a pointer might use low bits of address to show how many times the pointer has been successfully modified. Because of this, the next comparison-and-swap will fail, even though the address is the same, because the tag bit will not match. It does not completely solve the problem, because the tag bit will eventually wrap, but helps to avoid it. Some architectures provide comparison and multiple word exchanges, allowing for larger tags. This is sometimes called ABA? because the second A is made slightly different from the first. This tagged status reference is also used in transactional memory.
Intermediate node
The correct but costly approach is to use an intermediate node that is not a data element and thus ensure the invariant when the element is inserted and deleted [Valois].
Deferred reclamation
Another approach is to delay reclamation of deleted data elements. One way to delay reclamation is to run an algorithm in an environment that displays automatic garbage collector; the problem here is that if GC is not lock-free, then the whole system is not lock-free, despite its own data structure.
Another way to delay reclamation is to use one or more hazard pointers, pointing to locations that otherwise can not appear in the list. Each hazard pointer represents the intermediate state of an ongoing change; the presence of a pointer assures further synchronization [Doug Lea]. The hazard pointer is free of keys, but can only track at most two elements as it is being used.
Another way to delay reclamation is to use update copy (RCU), which involves attaching updates in the critical section of RCU reading and then waiting for the RCU grace period before releasing any deleted data elements. Using RCU in this way ensures that any deleted data elements can not reappear until all executed operations are completed. Unfortunately, RCU is not scaled, because all the work read is involved.
Some of the architectures provide "bigger" atomic operations so that, for example, the advanced and reverse links in multiple linked lists can be atomically updated (this is in fact applicable only to the Motorola 68k family, the latest version released in 1994).
Some architectures provide related loads, storing conditional instructions where a store is performed only when no other store from the location is shown. This effectively separates the idea of ââ"storage containing value" from "storage has changed". Examples include DEC Alpha, MIPS, PowerPC and ARM (v6 and later).
See also
- Reader-reader problems
References
-
Dechev, Damian; Pirkelbauer, Peter; Stroustrup, Bjarne. "Dynamic Lock Locks Locked for Free". CiteSeerXÃ, 10.1.1.86.2680 . - Dechev, Damian; Pirkelbauer, Peter; Stroustrup, Bjarne. "Understanding and Effectively Preventing ABA Problems in a Design Without A Key-Based Descriptor" (PDF) .
Source of the article : Wikipedia