decoupling lock free data structures from memory
play

Decoupling Lock-Free Data Structures from Memory Reclamation for - PowerPoint PPT Presentation

Decoupling Lock-Free Data Structures from Memory Reclamation for Static Analysis [POPL'19] Roland Meyer and Sebastian Wol ff TU Braunschweig, Germany Lock-free Queue (Michael&Scott) void dequeue() { Head a while (true) { head =


  1. Decoupling Lock-Free Data Structures from 
 Memory Reclamation for Static Analysis [POPL'19] Roland Meyer and Sebastian Wol ff TU Braunschweig, Germany

  2. Lock-free Queue (Michael&Scott) void dequeue() { Head a while (true) { head = Head; next = head -> next; b // ... if (CAS(Head, head, next)) { // leak head? c return; }}}

  3. Lock-free Queue (Michael&Scott) void dequeue() { Head a while (true) { 1 2 X head = Head; next = head -> next; b // ... if (CAS(Head, head, next)) { // leak head? c return; }}}

  4. Lock-free Queue (Michael&Scott) void dequeue() { Head head X a while (true) { 1 2 head = Head; X next = head -> next; b // ... if (CAS(Head, head, next)) { // leak head? c return; }}}

  5. Lock-free Queue (Michael&Scott) void dequeue() { head 1 Head head X a while (true) { head 2 head = Head; 1 2 X next = head -> next; b // ... if (CAS(Head, head, next)) { // leak head? c return; }}}

  6. Lock-free Queue (Michael&Scott) void dequeue() { head 1 Head head X a while (true) { head 2 head = Head; X next = head -> next; next 1 b next 2 // ... 1 2 if (CAS(Head, head, next)) { // leak head? c return; }}}

  7. Lock-free Queue (Michael&Scott) void dequeue() { head 1 head X a while (true) { head 2 head = Head; X next = head -> next; next 1 Head b next 2 // ... 2 if (CAS(Head, head, next)) { 1 // leak head? c return; }}}

  8. Lock-free Queue (Michael&Scott) void dequeue() { head 1 head X a while (true) { 2 head = Head; X next = head -> next; next 1 Head b // ... if (CAS(Head, head, next)) { 1 // leak head? c return; }}}

  9. Lock-free Queue (Michael&Scott) void dequeue() { head 1 head X a while (true) { head = Head; X next = head -> next; next 1 Head b head 2 // ... 2 if (CAS(Head, head, next)) { 1 // leak head? next 2 c return; }}}

  10. Lock-free Queue (Michael&Scott) void dequeue() { head 1 head X a while (true) { head = Head; X next = head -> next; next 1 b head 2 // ... if (CAS(Head, head, next)) { 1 2 // leak head? Head next 2 c return; }}}

  11. Lock-free Queue (Michael&Scott) void dequeue() { head 1 head X a while (true) { head = Head; X next = head -> next; next 1 b head 2 // ... if (CAS(Head, head, next)) { 1 2 delete head; Head next 2 c return; }}}

  12. Lock-free Queue (Michael&Scott) void dequeue() { head 1 head X a while (true) { head = Head; X next = head -> next; next 1 b head 2 // ... if (CAS(Head, head, next)) { delete head; Head next 2 c 1 2 return; }}}

  13. Lock-free Queue (Michael&Scott) void dequeue() { head 1 head X a while (true) { head = Head; X next = head -> next; next 1 b head 2 // ... if (CAS(Head, head, next)) { delete head; Head next 2 c 1 2 return; }}}

  14. Reclamation • Lock-free data structures (LFDS) ➡ unsynchronized traversal ➡ threads cannot detect whether a dereference is safe • Safe memory reclamation (SMR) ➡ defers deletion until it is safe ➡ controlled by LFDS ➡ various sophisticated techniques exist

  15. Lock-free Queue (Michael&Scott) data_t dequeue() { Head a while (true) { 1 X head = Head; protect(head); next = head -> next; b // ... if (CAS(Head, head, next)) { retire(head); c return; }}}

  16. Lock-free Queue (Michael&Scott) data_t dequeue() { Head head X a while (true) { 1 head = Head; protect(head); X next = head -> next; b // ... if (CAS(Head, head, next)) { retire(head); c return; }}}

  17. Lock-free Queue (Michael&Scott) data_t dequeue() { X Head head X a while (true) { 1 head = Head; protect(head); X next = head -> next; b // ... if (CAS(Head, head, next)) { retire(head); c return; }}}

  18. Lock-free Queue (Michael&Scott) data_t dequeue() { head 1 X Head head X a while (true) { head = Head; protect(head); 1 X next = head -> next; b // ... if (CAS(Head, head, next)) { retire(head); c return; }}}

  19. Lock-free Queue (Michael&Scott) data_t dequeue() { head 1 X Head head X a while (true) { head = Head; protect(head); 1 X next = head -> next; b // ... if (CAS(Head, head, next)) { retire(head); c return; }}}

  20. Lock-free Queue (Michael&Scott) data_t dequeue() { head 1 X head X a while (true) { head = Head; protect(head); next 1 X next = head -> next; Head b // ... if (CAS(Head, head, next)) { 1 retire(head); c return; }}}

  21. Lock-free Queue (Michael&Scott) Z Z Z data_t dequeue() { head 1 X head X a while (true) { head = Head; protect(head); next 1 X next = head -> next; Head b // ... if (CAS(Head, head, next)) { retire(head); c 1 return; }}}

  22. Lock-free Queue (Michael&Scott) Z Z Z data_t dequeue() { head 1 X a while (true) { X head = Head; protect(head); next 1 next = head -> next; Head b // ... if (CAS(Head, head, next)) { retire(head); c 1 return; }}}

  23. Lock-free Queue (Michael&Scott) Z Z Z data_t dequeue() { head 1 X a while (true) { head = Head; protect(head); X next 1 next = head -> next; Head head X b // ... if (CAS(Head, head, next)) { retire(head); c 1 return; }}}

  24. Lock-free Queue (Michael&Scott) Z Z Z data_t dequeue() { head 1 a while (true) { head = Head; protect(head); next 1 X X next = head -> next; Head head X b // ... if (CAS(Head, head, next)) { retire(head); c 1 return; }}}

  25. Lock-free Queue (Michael&Scott) data_t dequeue() { head 1 a while (true) { head = Head; protect(head); next 1 X X next = head -> next; Head head X b // ... if (CAS(Head, head, next)) { retire(head); c 1 return; }}}

  26. State-of-the-art Verification of Data Structures • Pen&paper, mechanized/tool-supported ➡ require deep understanding of proof technique, LFDS, and SMR ➡ few works consider reclamation • Automated (model-checking) ➡ only done for GC ➡ or custom semantics (allowing accesses of deleted memory) ➡ no works consider SMR

  27. Verification LFDS+SMR struct Node { shared: void init() { data_t data; Node* Head; Head = new Node(); Node* node; Node* Tail; Head-> next = null; } Tail = Head; } void enqueue(data_t val) { data_t dequeue() { Node* node = new Node(); while (true) { node->data = val; Node* head = Head; GC Implementation node->next = null; while (true) { Node* tail = Tail; Node* tail = Tail; Node* next = head -> next; (automated verification possible) Node* next = tail -> next; if (Head != head) continue; if (Tail != tail) continue; if (head == tail) { if (next == null) { if (next == null) return empty_t; if (CAS(tail->next, null, node)) { else CAS(Tail, tail, next); CAS(Tail, tail, node); } else { } data = head -> data; } else { if (CAS(Head, head, next)) { CAS(Tail, tail, next); } return data; } } } } } 46 LOC }

  28. Verification LFDS+SMR struct Node { shared: void init() { data_t data; Node* Head; Head = new Node(); Node* node; Node* Tail; Head-> next = null; } Tail = Head; } void enqueue(data_t val) { data_t dequeue() { Node* node = new Node(); while (true) { node->data = val; Node* head = Head; node->next = null; protect(head, 0); while (true) { if (Head != head) continue; Node* tail = Tail; Node* tail = Tail; protect(tail, 0); Node* next = head -> next; if (Tail != tail) continue; protect(next, 1); Node* next = tail -> next; if (Head != head) continue; if (Tail != tail) continue; if (head == tail) { if (next == null) { if (next == null) return empty_t; if (CAS(tail->next, null, node)) { else CAS(Tail, tail, next); CAS(Tail, tail, node); } else { } data = head -> data; } else { if (CAS(Head, head, next)) { CAS(Tail, tail, next); retire(head); } return data; } } } } } 46+6 LOC }

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend