![]() | ||
A non-blocking linked list is an example of non-blocking data structures designed to implement a linked list in shared memory using synchronization primitives:
Contents
- Review linked lists
- Harriss solution
- Basic idea
- Concurrent insert and delete
- Solutions
- Concurrent deletions
- References
Several strategies for implementing non-blocking lists have been suggested.
Review: linked lists
(Singly) linked lists are fundamental data structures that are widely used as is, or to build other data structures. They consist of "nodes", or "links", that are put in some order indicated by a "next" pointer on each node. The last node in the list (the "tail") has a nil next pointer. The first node (the "head") is a sentinel: it stores no interesting information and is only used for its next pointer.
The operations that must be supported on lists are as follows.
Both operations must support concurrent use: two or more threads of execution must be able to perform insertions and deletions without interfering with each other's work (see diagram).
Harris's solution
In a 2001 paper, Harris gives a solution to concurrent linked list maintenance that is non-blocking, using a compare-and-swap (cas) primitive. Insertion of n after p is simple:
- next ← p.next
- n.next ← next
- cas(address-of(p.next), next, n)
- If the cas was not successful, go back to 1.
Deletion of p.next is more involved. The naive solution of resetting this pointer with a single CAS runs the risk of losing data when another thread is simultaneously inserting (see diagram). Instead, two invocations of cas are needed for a correct algorithm. The first marks the pointer p.next as deleted, changing its value but in such a way that the original pointer can still be reconstructed. The second actually deletes the node by resetting p.next.
Basic idea
Basic idea
Basic idea
Concurrent insert and delete
Solutions
Concurrent deletions
Solutions
Valois