LockFree concurrent algorithm for Linked lists Implementation Speaker

  • Slides: 22
Download presentation
Lock-Free concurrent algorithm for Linked lists: Implementation Speaker: Alexandre Walzberg Date: April, 28 th

Lock-Free concurrent algorithm for Linked lists: Implementation Speaker: Alexandre Walzberg Date: April, 28 th 2009 Paper: Mikhail. Fomitchev and Eric Ruppert, Lock-Free Linked Lists and Skip Lists. PODC'04, 2004. CSE-COSC 6490 A : Concurrent Object-Oriented Languages York University - W 09 1

Plan 1. Implementation 2. Tests 3. Performances 2

Plan 1. Implementation 2. Tests 3. Performances 2

1. The Implementation Reminder: a node Node value 31 … 2 1 0 key

1. The Implementation Reminder: a node Node value 31 … 2 1 0 key 31 backlink 31 next 31 2 LSB of a pointer : always 0 ! - one will represent the flag - the other one the mark Allow to update the 3 information atomically 3

1. The Implementation Reminder: a node Node int value 31 … 2 1 0

1. The Implementation Reminder: a node Node int value 31 … 2 1 0 long key 31 Node backlink 31 … 2 1 0 next 31 2 LSB of a pointer : always 0 ! - one will represent the flag - the other one the mark Allow to update the 3 information atomically 4

1. The Implementation Atomic. Stamped. Reference<T> Own: • A reference to an object of

1. The Implementation Atomic. Stamped. Reference<T> Own: • A reference to an object of class T • A Stamp (integer) • Getters and Setters for the reference and the stamp • Atomic CAS operation which change both the reference and the stamp atomically • Reading and writing on both the reference and the stamp are Volatile public boolean compare. And. Set( V expected. Reference, V new. Reference, int expected. Stamp, int new. Stamp) 5

1. The Implementation The class Node int value 31 … 2 1 0 long

1. The Implementation The class Node int value 31 … 2 1 0 long key 31 Node backlink 31 … 2 1 0 Atomic. Stamped. Reference<T> next int Node … 31 2 1 0 31 … 2 1 0 6

1. The Implementation Flag and Mark Use the stamp to represent the Flag and

1. The Implementation Flag and Mark Use the stamp to represent the Flag and the Mark 0: flag=0 ; mark=0 1: flag=1 ; mark=0 2: flag=0 ; mark=1 compare. And. Set vs compare. And. Swap The paper’s algorithm was using compare. And. Swap. This is different of the compare. And. Set function java provides. => The way to use these atomic function differ a little bit ! (but the result is the same) 7

1. The Implementation Class concurrent. Linked. List private Node head, tail public Node Insert(),

1. The Implementation Class concurrent. Linked. List private Node head, tail public Node Insert(), Delete(), Search() public void print() private Search. From(), Search. From 2() private Try Flag(), Try. Mark(), Help. Flagged(), Help. Marked() concurrent. Linked. List Node head Node … Node tail 8

1. The Implementation Example: Insert(7) public Node Insert(long k, int value){ … // search

1. The Implementation Example: Insert(7) public Node Insert(long k, int value){ … // search where to insert ; allocate new node while(true){ if(prev. Node. get. Flags() == FLAG) Help. Flagged(prev. Node, prev. Node. get. Next()); else{ new. Node. set. Next. And. Flag(next. Node, NONE); int result = prev. Node. CASnext(next. Node, new. Node, NONE); if(result == NONE && prev. Node. get. Next()== new. Node) return new. Node; else{ if(result == FLAG) Help. Flagged(prev. Node, prev. Node. get. Next()); while(prev. Node. get. Flags() == MARK) prev. Node = prev. Node. get. Backlink(); } } (prev. Node, next. Node) = Search. From(k, prev. Node); if(prev. Node. get. Key() == k) return null; } } 5 10 13 9

1. The Implementation Example: Insert(7) public Node Insert(long k, int value){ … // search

1. The Implementation Example: Insert(7) public Node Insert(long k, int value){ … // search where to insert ; allocate new node while(true){ if(prev. Node. get. Flags() == FLAG) Help. Flagged(prev. Node, prev. Node. get. Next()); else{ new. Node. set. Next. And. Flag(next. Node, NONE); int result = prev. Node. CASnext(next. Node, new. Node, NONE); if(result == NONE && prev. Node. get. Next()== new. Node) return new. Node; else{ if(result == FLAG) Help. Flagged(prev. Node, prev. Node. get. Next()); while(prev. Node. get. Flags() == MARK) prev. Node = prev. Node. get. Backlink(); } } (prev. Node, next. Node) = Search. From(k, prev. Node); if(prev. Node. get. Key() == k) return null; } } prev. Node next. Node 10 5 new. Node 7 13 10

1. The Implementation Example: Insert(7) public Node Insert(long k, int value){ … // search

1. The Implementation Example: Insert(7) public Node Insert(long k, int value){ … // search where to insert ; allocate new node while(true){ if(prev. Node. get. Flags() == FLAG) Help. Flagged(prev. Node, prev. Node. get. Next()); else{ new. Node. set. Next. And. Flag(next. Node, NONE); int result = prev. Node. CASnext(next. Node, new. Node, NONE); if(result == NONE && prev. Node. get. Next()== new. Node) return new. Node; else{ if(result == FLAG) Help. Flagged(prev. Node, prev. Node. get. Next()); while(prev. Node. get. Flags() == MARK) prev. Node = prev. Node. get. Backlink(); } } (prev. Node, next. Node) = Search. From(k, prev. Node); if(prev. Node. get. Key() == k) return null; Will be deleted } } prev. Node next. Node 10 5 new. Node 7 13 11

1. The Implementation Example: Insert(7) public Node Insert(long k, int value){ … // search

1. The Implementation Example: Insert(7) public Node Insert(long k, int value){ … // search where to insert ; allocate new node while(true){ if(prev. Node. get. Flags() == FLAG) Help. Flagged(prev. Node, prev. Node. get. Next()); else{ new. Node. set. Next. And. Flag(next. Node, NONE); int result = prev. Node. CASnext(next. Node, new. Node, NONE); if(result == NONE && prev. Node. get. Next()== new. Node) return new. Node; else{ if(result == FLAG) Help. Flagged(prev. Node, prev. Node. get. Next()); while(prev. Node. get. Flags() == MARK) prev. Node = prev. Node. get. Backlink(); } } (prev. Node, next. Node) = Search. From(k, prev. Node); if(prev. Node. get. Key() == k) return null; } } prev. Node next. Node 13 5 new. Node 7 12

1. The Implementation Example: Insert(7) public Node Insert(long k, int value){ … // search

1. The Implementation Example: Insert(7) public Node Insert(long k, int value){ … // search where to insert ; allocate new node while(true){ if(prev. Node. get. Flags() == FLAG) Help. Flagged(prev. Node, prev. Node. get. Next()); else{ new. Node. set. Next. And. Flag(next. Node, NONE); int result = prev. Node. CASnext(next. Node, new. Node, NONE); if(result == NONE && prev. Node. get. Next()== new. Node) return new. Node; else{ if(result == FLAG) Help. Flagged(prev. Node, prev. Node. get. Next()); while(prev. Node. get. Flags() == MARK) prev. Node = prev. Node. get. Backlink(); } } (prev. Node, next. Node) = Search. From(k, prev. Node); if(prev. Node. get. Key() == k) return null; } } prev. Node next. Node 13 5 new. Node 7 13

1. The Implementation Example: Insert(7) public Node Insert(long k, int value){ … // search

1. The Implementation Example: Insert(7) public Node Insert(long k, int value){ … // search where to insert ; allocate new node while(true){ if(prev. Node. get. Flags() == FLAG) Help. Flagged(prev. Node, prev. Node. get. Next()); else{ new. Node. set. Next. And. Flag(next. Node, NONE); CASnext int result = prev. Node. CASnext(next. Node, new. Node, NONE); 1) if(result == NONE && prev. Node. get. Next()== new. Node) return new. Node; else{ if(result == FLAG) Help. Flagged(prev. Node, prev. Node. get. Next()); 2) else while(prev. Node. get. Flags() == MARK) prev. Node = prev. Node. get. Backlink(); 3) } } (prev. Node, next. Node) = Search. From(k, prev. Node); if(prev. Node. get. Key() == k) return null; } } prev. Node next. Node 13 5 new. Node 7 14

1. The Implementation Example: Insert(7) public Node Insert(long k, int value){ … // search

1. The Implementation Example: Insert(7) public Node Insert(long k, int value){ … // search where to insert ; allocate new node while(true){ if(prev. Node. get. Flags() == FLAG) Help. Flagged(prev. Node, prev. Node. get. Next()); else{ new. Node. set. Next. And. Flag(next. Node, NONE); int result = prev. Node. CASnext(next. Node, new. Node, NONE); if(result == NONE && prev. Node. get. Next()== new. Node) return new. Node; else{ if(result == FLAG) Help. Flagged(prev. Node, prev. Node. get. Next()); while(prev. Node. get. Flags() == MARK) prev. Node = prev. Node. get. Backlink(); } } (prev. Node, next. Node) = Search. From(k, prev. Node); if(prev. Node. get. Key() == k) return null; } } And so on… 15

2. Testing Classes concurrent. Linked. List Node Thread list. User 16

2. Testing Classes concurrent. Linked. List Node Thread list. User 16

2. Testing Interleaving Concurrent insertion/deletion of nodes 1) with same key 2) with different

2. Testing Interleaving Concurrent insertion/deletion of nodes 1) with same key 2) with different key 3) with same and different key Insertion of all even key Insertion of odd key | Deletion of even key Pre-emption effects Insertion of sleep(100) into delete-group functions to force pre-emption by the scheduler in the middle of a deletion (between each step) => Test of the lock-free property and distribution of the algorithm 17

2. Testing Random • Insertion and deletion after random delay • Random operation (search

2. Testing Random • Insertion and deletion after random delay • Random operation (search / insert / delete) => TODO • Random key => TODO Plan for Verification • Finish testing • To make the algorithm works : I add an operation compare to the described algorithm => seems to work this way but need to be CHECK • See what tools can offer for lock-free algorithm verification 18

3. Performances Locks implementation Source: http: //docsun. cites. uiuc. edu/sun_docs/C/solaris_9/SUNWdev/MTP/p 26. html • One

3. Performances Locks implementation Source: http: //docsun. cites. uiuc. edu/sun_docs/C/solaris_9/SUNWdev/MTP/p 26. html • One mutex / node • Lock node during research / insertion before reading the next field • Deletion: lock the previous node and then the deleted node • Implemented with the finest possible granularity 19

3. Performances Test done on navy (8 processors) 20

3. Performances Test done on navy (8 processors) 20

Conclusion Implementation easy to do (just translate the paper algorithm) => be carefully with

Conclusion Implementation easy to do (just translate the paper algorithm) => be carefully with some little details (compare. And. Set vs Compare. And. Swap) => some unexpected bugs very hard to trace and debug Seems to work well according to the test done => Are the tests cover all cases? The lock-free algorithm is much more efficient than the lock based one. => Is that possible to improve the lock-based algorithm? 21

Any questions ? ? Thank you for your attention! 22

Any questions ? ? Thank you for your attention! 22