lock free algorithms for kotlin coroutines
play

Lock-free algorithms for Kotlin coroutines It is all about - PowerPoint PPT Presentation

Lock-free algorithms for Kotlin coroutines It is all about scalability Presented at SPTCC 2017 /Roman Elizarov @ JetBrains Speaker: Roman Elizarov 16+ years experience Previously developed high-perf trading software @ Devexperts


  1. Senders wait More Incoming senders receivers Sender #1 Sender #2 Sender #3 H T Receiver removes Sender inserts last if it first if it is a sender is not a receiver node node

  2. Receivers wait More Incoming receivers senders Receiver #1 Receiver #2 Receiver #3 H T Sender removes Receiver inserts last if first if it is a receiver it is not a sender node node

  3. Send function sketch fun send(element: T) { 1 while ( true ) { // try to add sender, unless prev is receiver 2 if (enqueueSend(element)) break // try to remove first receiver 3 val receiver = removeFirstReceiver() if (receiver != null ) { 4 receiver.resume(element) // resume receiver break } } }

  4. Channel use-case recap • Uses insert/remove ops conditional on tail/head node • Can abort (cancel) wait to receive/send at any time by using remove • Full removal -- no garbage is left • Pretty efficient in practice • One item lists – one “garbage” object

  5. Multi-word compare and swap (CASN) Build even bigger atomic operations

  6. Use-case: select expression val channel1 = Channel<Int>() val channel2 = Channel<Int>() select { channel1. onReceive { e -> ... } channel2. onReceive { e -> ... } }

  7. Impl summary: register (1) 1. Not selected Select 2. Selected status: NS Channel1 Channel2 Queue Queue

  8. Impl summary: register (2) Select Add node to channel1 queue if status: NS not selected (NS) yet Channel1 Channel2 Queue Queue N1

  9. Impl summary: register (3) Select Add node to channel2 queue if status: NS not selected (NS) yet Channel1 Channel2 Queue Queue N1 N2

  10. Impl summary: wait Select status: NS Channel1 Channel2 Queue Queue N1 N2

  11. Impl summary: select (resume) Select Make selected and remove node status: S from queue Channel1 Channel2 Queue Queue N1

  12. Impl summary: clean up rest Select Remove non-selected waiters status: S from queue Channel1 Channel2 Queue Queue

  13. Double-Compare Single-Swap (DCSS) Building block for CASN

  14. DCSS spec in pseudo-code A B fun <A,B> dcss( 1 a: Ref<A>, expectA: A, updateA: A, b: Ref<B>, expectB: B) = 2 atomic { 3 if (a. value == expectA && b. value == expectB) { 4 a. value = updateA } }

  15. DCSS: init descriptor expectA A B expectB updateA DCSS Descriptor (a, expectA, updateA, b, expectB)

  16. DCSS: prepare expectA A B expectB CAS ptr to descriptor if a. value == expectA updateA DCSS Descriptor (a, expectA, updateA, b, expectB)

  17. DCSS: read b.value expectA A B expectB CAS ptr to descriptor if a. value == expectA updateA DCSS Descriptor (a, expectA, updateA, b, expectB)

  18. DCSS: complete (when success) expectA A B expectB CAS to updated value if a still points to descriptor updateA DCSS Descriptor (a, expectA, updateA, b, expectB)

  19. DCSS: complete (alternative) expectA A B !expectB updateA DCSS Descriptor (a, expectA, updateA, b, expectB)

  20. DCSS: complete (when fail) expectA A B !expectB CAS to original value if a still points to descriptor updateA DCSS Descriptor (a, expectA, updateA, b, expectB)

  21. DCSS: States Any other thread encountering descriptor helps complete 1 2 3 Init prep ok success A: desc A: updateA A: ??? A was expectA B was expectB (desc created) prep fail fail 4 5 Originator cannot A: ??? A: expectA learn what was the A was !expectA B was !expectB outcome Lock-free algorithm without loops! one tread

  22. Caveats • A & B locations must be totally ordered • or risk stack-overflow while helping • One way to look at it: Restricted DCSS (RDCSS)

  23. DCSS Mod: learn outcome A B fun <A,B> dcssMod( a: Ref<A>, expectA: A, updateA: A, b: Ref<B>, expectB: B): Boolean = atomic { if (a. value == expectA && b. value == expectB) { a. value = updateA true } else false }

  24. DCSS Mod: init descriptor expectA A B expectB updateA DCSS Descriptor (a, expectA, updateA, b, expectB) Outcome: UNDECIDED Consensus

  25. DCSS Mod: prepare expectA A B expectB updateA DCSS Descriptor (a, expectA, updateA, b, expectB) Outcome: UNDECIDED

  26. DCSS Mod: read b.value expectA A B expectB updateA DCSS Descriptor (a, expectA, updateA, b, expectB) Outcome: UNDECIDED

  27. DCSS Mod: reach consensus expectA A B expectB updateA DCSS Descriptor (a, expectA, updateA, b, expectB) Outcome: SUCCESS CAS(UNDECIDED, DECISION)

  28. DCSS Mod: complete expectA A B expectB updateA DCSS Descriptor (a, expectA, updateA, b, expectB) Outcome: SUCCESS

  29. DCSS Mod: States 1 2 3 Init A: desc A: desc prep ok success A: ??? Outcome: UND Outcome: SUCC Outcome: UND A was expectA B was expectB (desc created) prep fail fail 4 5 6 A: updateA A: ??? A: desc Outcome: FAIL Outcome: FAIL 7 A was !expectA A: expectA Still no loops! one tread

  30. Compare-And-Swap N-words (CASN) The ultimate atomic update

  31. CASN spec in pseudo-code For two words, for simplicity A B fun <A,B> cas2( 1 a: Ref<A>, expectA: A, updateA: A, b: Ref<B>, expectB: B, updateB: B): Boolean = 2 atomic { 3 if (a. value == expectA && b. value == expectB) { a. value = updateA 4 b. value = updateB true } else 5 false }

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