using abstract interpretation to correct synchronization
play

Using abstract interpretation to correct synchronization faults - PowerPoint PPT Presentation

Using abstract interpretation to correct synchronization faults Pietro Ferrara Omer Tripp Peng Liu Eric Koskinen JuliaSoft Google IBM Research Yale University VMCAI 17 January 2017 Concurrency is here to stay. Thread 1 Thread 2


  1. Using abstract interpretation to correct synchronization faults Pietro Ferrara Omer Tripp Peng Liu Eric Koskinen JuliaSoft Google IBM Research Yale University VMCAI · 17 January 2017

  2. Concurrency is here to stay.

  3. … Thread 1 Thread 2 Thread n Queue HashMap List

  4. updateReservation(Slot old_slot, Slot new_slot) : Reservation = { var r = map. remove (old_slot) // remove if exists if (r == null) { Slot Res r = new Res() } 10:00 α val clobbered = map. replace (new_slot, r) return clobbered; 11:00 β } 12:00 γ 13:00 —

  5. updateReservation(Slot old_slot, Slot new_slot) : Reservation = { var r = map. remove (old_slot) // remove if exists if (r == null) { Slot Res r = new Res() } 10:00 α t 1 val clobbered = map. replace (new_slot, r) return clobbered; 11:00 β } t 2 12:00 γ 13:00 —

  6. updateReservation(Slot old_slot, Slot new_slot) : Reservation = { var r = map. remove (old_slot) // remove if exists if (r == null) { Slot Res r = new Res() } 10:00 α t 1 val clobbered = map. replace (new_slot, r) return clobbered; 11:00 β } t 2 12:00 γ t 1 goes first 13:00 — t 2 goes second t 1 : remove (10:00) / α t 2 : remove (13:00) / null t 1 : if (…) t 2 : new Res() / δ t 2 : replace (11:00) / β But returns δ ? Now: 11:00 —> α t 1 : replace (11:00) / δ t 1 : return δ Returns β ? Not serializable! t 2 : return β

  7. updateReservation(Slot old_slot, Slot new_slot) : Reservation = { var r = map. remove (old_slot) // remove if exists if (r == null) { Slot Res r = new Res() } 10:00 α t 1 val clobbered = map. replace (new_slot, r) return clobbered; 11:00 β } t 2 12:00 γ 13:00 — Acceptable Final States: t 1 first, returns β t 2 first, returns β t 2 second, returns α t 1 second, returns δ Slot Res Slot Res 10:00 — 10:00 — 11:00 δ 11:00 α 12:00 γ 12:00 γ 13:00 — 13:00 —

  8. updateReservation(Slot old_slot, Slot new_slot) : Reservation = { var r = map. remove (old_slot) // remove if exists if (r == null) { Slot Res r = new Res() } 10:00 α t 1 val clobbered = map. replace (new_slot, r) return clobbered; 11:00 β } t 2 12:00 γ 13:00 — Existing approaches to enforcing serializability . . .

  9. updateReservation(Slot old_slot, Slot new_slot) : Reservation = { var r = map. remove (old_slot) // remove if exists if (r == null) { Slot Res r = new Res() } t 1 10:00 α t 1 val clobbered = map. replace (new_slot, r) t 1 return clobbered; 11:00 β } t 2 12:00 γ t 2 Pessimistic 13:00 — t 1 : lock (10:00); lock (11:00) t 2 : lock (13:00); t 1 : remove (10:00) / α t 1 : if (…) t 1 : replace (11:00) / β t 1 : return β

  10. updateReservation(Slot old_slot, Slot new_slot) : Reservation = { var r = map. remove (old_slot) // remove if exists if (r == null) { Slot Res r = new Res() } t 1 10:00 α t 1 val clobbered = map. replace (new_slot, r) t 1 return clobbered; 11:00 β } t 2 12:00 γ t 2 Pessimistic 13:00 — t 1 : lock (10:00); lock (11:00) t 2 : lock (13:00); lock (11:00) t 1 : remove (10:00) / α t 1 : if (…) t 1 : replace (11:00) / β t 1 : return β

  11. updateReservation(Slot old_slot, Slot new_slot) : Reservation = { var r = map. remove (old_slot) // remove if exists if (r == null) { r = new Res() } val clobbered = map. replace (new_slot, r) return clobbered; } Pessimistic pessimis,c% remove if replace t 1 % get$ if(…)$ new$ putIfAbsent$ return$ remove new replace t 2 % get$ if(…)$ new$ putIfAbsent$ return$

  12. updateReservation(Slot old_slot, Slot new_slot) : Reservation = { var r = map. remove (old_slot) // remove if exists if (r == null) { r = new Res() } val clobbered = map. replace (new_slot, r) return clobbered; } Optimistic t 1 : remove (10:00) / α t 2 : remove (13:00) / null t 1 : if (…) t 2 : new Res() / δ t 2 : replace (11:00) / β t 1 : replace (11:00) / β t 1 : return β t 2 : return β

  13. updateReservation(Slot old_slot, Slot new_slot) : Reservation = { var r = map. remove (old_slot) // remove if exists if (r == null) { r = new Res() } val clobbered = map. replace (new_slot, r) return clobbered; } Optimistic t 1 : remove (10:00) / α t 2 : remove (13:00) / null t 1 : if (…) t 2 : new Res() / δ t 2 : replace (11:00) / β t 1 : replace (11:00) / β conflict. t 1 : return β t 2 : return β

  14. updateReservation(Slot old_slot, Slot new_slot) : Reservation = { var r = map. remove (old_slot) // remove if exists if (r == null) { r = new Res() } val clobbered = map. replace (new_slot, r) return clobbered; } Optimistic pessimis,c% remove if replace t 1 % get$ if(…)$ new$ putIfAbsent$ return$ remove new replace t 2 % get$ if(…)$ new$ putIfAbsent$ return$ remove if replace op,mis,c% t 1 % get$ if(…)$ new$ putIfAbsent$ return$ t 2 % remove new replace remove new replace get$ if(…)$ new$ putIfAbsent$ get$ if(…)$ new$ putIfAbsent$ return$ retry%

  15. updateReservation(Slot old_slot, Slot new_slot) : Reservation = { var r = map. remove (old_slot) // remove if exists if (r == null) { r = new Res() } val clobbered = map. replace (new_slot, r) return clobbered; } Other options? Perform a correction!

  16. updateReservation(Slot old_slot, Slot new_slot) : Reservation = { var r = map. remove (old_slot) // remove if exists if (r == null) { Slot Res r = new Res() } 10:00 α t 1 val clobbered = map. replace (new_slot, r) return clobbered; 11:00 β } t 2 12:00 γ 13:00 — t 1 : remove (10:00) / α t 2 : remove (13:00) / null t 1 : if (…) t 2 : new Res() / δ t 2 : replace (11:00) / β t 1 : replace (11:00) / δ t 1 : return δ Not serializable! t 2 : return β

  17. updateReservation(Slot old_slot, Slot new_slot) : Reservation = { var r = map. remove (old_slot) // remove if exists if (r == null) { Slot Res r = new Res() } 10:00 α t 1 val clobbered = map. replace (new_slot, r) return clobbered; 11:00 β } t 2 12:00 γ 13:00 —

  18. Serializable Target t 1 first, returns β updateReservation(Slot old_slot, Slot new_slot) : Reservation = { var r = map. remove (old_slot) // remove if exists t 2 second, returns α if (r == null) { Slot Res r = new Res() ♥ Slot Res } 10:00 — val clobbered = map. replace (new_slot, r) 10:00 — δ return clobbered; 11:00 β } 11:00 δ 12:00 γ 12:00 γ 13:00 — 13:00 — t 1 : remove (10:00) / α t 2 : remove (13:00) / null t 1 : if (…) t 2 : new Res() / δ t 2 : replace (11:00) / β α t 1 : replace (11:00) / δ β t 1 : return δ β t 2 : return β α

  19. Serializable Target t 2 first, returns β updateReservation(Slot old_slot, Slot new_slot) : Reservation = { var r = map. remove (old_slot) // remove if exists t 1 second, returns δ if (r == null) { Slot Res r = new Res() ♥ Slot Res } 10:00 — val clobbered = map. replace (new_slot, r) 10:00 — α return clobbered; 11:00 β } 11:00 α 12:00 γ 12:00 γ 13:00 — 13:00 — t 1 : remove (10:00) / α t 2 : remove (13:00) / null t 1 : if (…) t 2 : new Res() / δ t 2 : replace (11:00) / β t 1 : replace (11:00) / δ t 1 : return δ t 2 : return β

  20. updateReservation(Slot old_slot, Slot new_slot) : Reservation = { var r = map. remove (old_slot) // remove if exists if (r == null) { r = new Res() } val clobbered = map. replace (new_slot, r) return clobbered; } Corrective pessimis,c% remove if replace t 1 % get$ if(…)$ new$ putIfAbsent$ return$ remove new replace t 2 % get$ if(…)$ new$ putIfAbsent$ return$ remove if replace op,mis,c% t 1 % get$ if(…)$ new$ putIfAbsent$ return$ t 2 % remove new replace remove new replace get$ if(…)$ new$ putIfAbsent$ get$ if(…)$ new$ putIfAbsent$ return$ retry% remove if replace correc,ve% t 1 % get$ if(…)$ new$ putIfAbsent$ return$ remove new replace t 2 % get$ if(…)$ new$ putIfAbsent$ return$ correct%

  21. remove if replace correc,ve% t 1 % get$ if(…)$ new$ putIfAbsent$ return$ Corrective remove new replace t 2 % get$ if(…)$ new$ putIfAbsent$ return$ correct% Challenges & Contributions • Is this serializable? 
 Yes, we have proved so. • How to compute each thread’s alternative post- states? 
 Via a static abstract interpretation . • Given an incorrect state, how to efficiently recover to a correct post-state? 
 Via a dynamic runtime system .

  22. remove if replace correc,ve% t 1 % get$ if(…)$ new$ putIfAbsent$ return$ Corrective remove new replace t 2 % get$ if(…)$ new$ putIfAbsent$ return$ correct% Formalization Transition System

  23. remove if replace correc,ve% t 1 % get$ if(…)$ new$ putIfAbsent$ return$ Corrective remove new replace t 2 % get$ if(…)$ new$ putIfAbsent$ return$ correct% Formalization Remember where we started t

  24. remove if replace correc,ve% t 1 % get$ if(…)$ new$ putIfAbsent$ return$ Corrective remove new replace t 2 % get$ if(…)$ new$ putIfAbsent$ return$ correct% Formalization Remember the operation that was performed , op t ) L t ' , L t •op t )], σ , L ) Act sort of optimistically: march ahead w local changes

  25. remove if replace correc,ve% t 1 % get$ if(…)$ new$ putIfAbsent$ return$ Corrective remove new replace t 2 % get$ if(…)$ new$ putIfAbsent$ return$ correct% Formalization Parameterize by property of interest (Serializability) , op t ) L t , L t •op t )], σ , L ) Replay the mutations on the shared state

Recommend


More recommend