relaxed linear references for lock free data structures
play

Relaxed Linear References for Lock-free Data Structures Elias - PowerPoint PPT Presentation

Relaxed Linear References for Lock-free Data Structures Elias Castegren , Tobias Wrigstad ECOOP17, Barcelona sa Structured Aliasing http://www.kristianstadik.se/www/wordpress/wp-content/uploads/2016/06/midsommar.jpg


  1. Relaxed Linear References for Lock-free Data Structures Elias Castegren , Tobias Wrigstad ECOOP’17, Barcelona sa Structured Aliasing

  2. http://www.kristianstadik.se/www/wordpress/wp-content/uploads/2016/06/midsommar.jpg http://www.vikstroms.nu/cms/wp-content/uploads/2014/06/Midsommar-2014.png http://pix.tagapi.aller.se/sf.php?src=http://stilexperten.mabra.com/wp-content/uploads/sites/ 2 36/2016/06/383ab62d304910ab9e9bb9a0f197d918.jpg&w=640&h=400&a=c

  3. http://2.bp.blogspot.com/-ed71CELc5pY/T-h5pPLBR-I/AAAAAAAAAck/9hILp4JdDJg/s1600/annicasxperia+juni+026.jpg 3

  4. ”Små grodorna är lustiga att se” https://upload.wikimedia.org/wikipedia/en/e/e7/The_Swedish_Chef.jpg https://68.media.tumblr.com/5cab6229774bfb3fa6a35bf3479b6f8c/ tumblr_inline_nht61yoHMA1r0y63m.jpg https://s3.amazonaws.com/gs-geo-images/ 4 3738763b-2dc4-47fb-81d2-345908ddbc07_l.jpg

  5. Lock-free Programming • Fine-grained concurrency achieved by following some protocol 1. Read a shared value (speculation) 2. Perform some local computation 3. If the speculation is still valid, make the local value global (publication) • Requires atomic operations, e.g. CAS (compare-and-swap) def CAS(x.f, y, z) : bool { } Performed atomically if (x.f == y) { x.f = z; return true; } else return false; } 5

  6. Example: A Lock-free Stack [Treiber] struct Node { struct Stack { var elem : T; var top : Node; val next : Node; } } top next N N N Stack elem T T T 6

  7. Example: A Lock-free Stack [Treiber] def pop(s : Stack) : T { while (true) { val oldTop = s.top; if (CAS(s.top, oldTop, oldTop.next)) return oldTop.elem; } } top N N N Stack T T T 7

  8. Example: A Lock-free Stack [Treiber] def pop(s : Stack) : T { while (true) { val oldTop = s.top; if (CAS(s.top, oldTop, oldTop.next)) return oldTop.elem; } } oldTop top N N N Stack T T T 7

  9. Example: A Lock-free Stack [Treiber] def pop(s : Stack) : T { while (true) { val oldTop = s.top; if (CAS(s.top, oldTop, oldTop.next)) return oldTop.elem; oldTop } } oldTop top N N N Stack T T T 7

  10. Example: A Lock-free Stack [Treiber] def pop(s : Stack) : T { while (true) { val oldTop = s.top; if (CAS(s.top, oldTop, oldTop.next)) return oldTop.elem; oldTop } } oldTop top N N N Stack T T T 7

  11. Example: A Lock-free Stack [Treiber] def pop(s : Stack) : T { while (true) { val oldTop = s.top; if (CAS(s.top, oldTop, oldTop.next)) return oldTop.elem; oldTop } } oldTop top N N N Stack T T T 7

  12. Example: A Lock-free Stack [Treiber] def pop(s : Stack) : T { while (true) { val oldTop = s.top; if (CAS(s.top, oldTop, oldTop.next)) return oldTop.elem; oldTop } } oldTop top N N N Stack T T T 7

  13. Example: A Lock-free Stack [Treiber] def pop(s : Stack) : T { while (true) { val oldTop = s.top; if (CAS(s.top, oldTop, oldTop.next)) return oldTop.elem; oldTop } } oldTop top N N N Stack T T T 7

  14. Example: A Lock-free Stack [Treiber] def pop(s : Stack) : T { while (true) { val oldTop = s.top; if (CAS(s.top, oldTop, oldTop.next)) return oldTop.elem; oldTop } } oldTop top N N N Stack T T T 7

  15. Example: A Lock-free Stack [Treiber] def pop(s : Stack) : T { while (true) { val oldTop = s.top; if (CAS(s.top, oldTop, oldTop.next)) return oldTop.elem; oldTop } } oldTop top N N N Stack T T T 7

  16. Example: A Lock-free Queue [Michael & Scott] struct Node { struct Queue { var elem : T; var first : Node; var next : Node; var last : Node } } last first next Queue N N N elem T T T 8

  17. Example: A Lock-free Queue [Michael & Scott] def enqueue(q : Queue, x : Elem) : void { val n = new Node(x); val done = false; while (not done) { val oldLast = q.last; done = CAS(oldLast.next, null , n); q.last = oldLast.next; } } Queue N N N T T T 9

  18. Example: A Lock-free Queue [Michael & Scott] def enqueue(q : Queue, x : Elem) : void { val n = new Node(x); val done = false; while (not done) { val oldLast = q.last; done = CAS(oldLast.next, null , n); q.last = oldLast.next; } } n Queue N N N N T T T T 9

  19. Example: A Lock-free Queue [Michael & Scott] def enqueue(q : Queue, x : Elem) : void { val n = new Node(x); val done = false; while (not done) { val oldLast = q.last; done = CAS(oldLast.next, null , n); q.last = oldLast.next; } } n oldLast Queue N N N N T T T T 9

  20. Example: A Lock-free Queue [Michael & Scott] def enqueue(q : Queue, x : Elem) : void { val n = new Node(x); val done = false; while (not done) { val oldLast = q.last; done = CAS(oldLast.next, null , n); q.last = oldLast.next; } } n oldLast Queue N N N N T T T T 9

  21. Example: A Lock-free Queue [Michael & Scott] def enqueue(q : Queue, x : Elem) : void { val n = new Node(x); val done = false; while (not done) { val oldLast = q.last; done = CAS(oldLast.next, null , n); q.last = oldLast.next; oldLast } } n oldLast Queue N N N N T T T T 9

  22. Example: A Lock-free Queue [Michael & Scott] def enqueue(q : Queue, x : Elem) : void { val n = new Node(x); val done = false; while (not done) { val oldLast = q.last; done = CAS(oldLast.next, null , n); q.last = oldLast.next; oldLast } } n oldLast Queue N N N N T T T T 9

  23. Finding Patterns in Lock-free Programming def enqueue(q : Queue, x : Elem) : void { • Speculation val n = new Node(x); val done = false; • Publication while (not done) { • Acquisition val oldLast = q.last; done = CAS(oldLast.next, null , n); q.last = oldLast.next; def dequeue(q : Queue) : T { } ... } } def pop(s : Stack) : T { def push(s : Stack, x : T) : void { while (true) { ... val oldTop = s.top; } if (CAS(s.top, oldTop, oldTop.next)) return oldTop.elem; } } 10

  24. Finding Patterns in Lock-free Programming def enqueue(q : Queue, x : Elem) : void { • Speculation val n = new Node(x); • Publication val done = false; while (not done) { • Acquisition val oldLast = q.last; done = CAS(oldLast.next, null , n); q.last = oldLast.next; def dequeue(q : Queue) : T { } Field ’last’ is subject to races and ... } must be written to with a CAS. } def pop(s : Stack) : T { def push(s : Stack, x : T) : void { while (true) { ... Our idea: Give these concepts val oldTop = s.top; } if (CAS(s.top, oldTop, oldTop.next)) meaningful types! return oldTop.elem; } } 10

  25. Why Types? • Why not model checking, concurrent separation logic, etc.? • Modularity: no need for inter-procedural analysis • Language expressivity: allow concurrent data structures storing linear references X X X 11

  26. Why Types? • Why not model checking, concurrent separation logic, etc.? • Modularity: no need for inter-procedural analysis • Language expressivity: allow concurrent data structures storing linear references X X X 12

  27. Linear References for Ownership Transfer • A linear reference is the only reference to an object • Prohibits shared access to objects • Makes ownership explicit X 13

  28. Linear References for Ownership Transfer • A linear reference is the only reference to an object • Prohibits shared access to objects • Makes ownership explicit X • A correct lock-free data-structure can guarantee exclusive ownership of an element — Can we use linear references to capture this? 13

  29. Linear References and Lock-free Programming def pop(s : Stack) : T { Aliasing! while (true) { val oldTop = s.top; if (CAS(s.top, oldTop, oldTop.next)) return oldTop.elem; } } Sharing! Aliasing! N N N Stack T T T 14

  30. Relaxed Linear References • Separate aliasing from ownership - Unbounded aliasing, linear ownership - Ownership can be atomically transferred between aliases 0 1 1 1 0 15

  31. Relaxed Linear References • Separate aliasing from ownership - Unbounded aliasing, linear ownership - Ownership can be atomically transferred between aliases 0 0 1 1 1 16

  32. Relaxed Linear References • Separate aliasing from ownership - Unbounded aliasing, linear ownership - Ownership can be atomically transferred between aliases 1 0 1 0 1 17

  33. CAT Atomic Ownership Transfer with CAS CAT(x.f, y, z) — ”Transfer ownership of x.f to y and of z to x.f ” 1 z B2 C2 x 1 f A B1 C1 y 0 19

  34. CAT Atomic Ownership Transfer with CAS CAT(x.f, y, z) — ”Transfer ownership of x.f to y and of z to x.f ” 0 z B2 C2 1 x f A B1 C1 y 1 19

  35. Ownership Transfer in Action def pop(s : Stack) : T { while (true) { val oldTop = s.top; if (CAT(s.top, oldTop, oldTop.next)) return oldTop.elem; } } 1 1 top N N N Stack T T T 20

  36. Ownership Transfer in Action def pop(s : Stack) : T { while (true) { val oldTop = s.top; if (CAT(s.top, oldTop, oldTop.next)) return oldTop.elem; } } 1 1 top N N N Stack T T T 20

  37. Ownership Transfer in Action def pop(s : Stack) : T { while (true) { val oldTop = s.top; if (CAT(s.top, oldTop, oldTop.next)) return oldTop.elem; } } 1 1 top N N N Stack T T T 20

  38. Ownership Transfer in Action def pop(s : Stack) : T { while (true) { val oldTop = s.top; if (CAT(s.top, oldTop, oldTop.next)) return oldTop.elem; } } 1 1 top N N N Stack T T T 20

  39. Ownership Transfer in Action def pop(s : Stack) : T { while (true) { val oldTop = s.top; if (CAT(s.top, oldTop, oldTop.next)) return oldTop.elem; } } 1 1 top N N N Stack T T T 20

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