programming and proving with concurrent resources
play

Programming and Proving with Concurrent Resources Ilya Sergey - PowerPoint PPT Presentation

Programming and Proving with Concurrent Resources Ilya Sergey joint work with Aleks Nanevski, Anindya Banerjee, Ruy Ley-Wild and Germn Delbianco What and why Concurrency parallelism efficiency A gap between informal


  1. A stack client program • Two threads: producer and consumer • Ap — an n -element producer array • Ac — an n -element consumer array • A shared concurrent stack S is used as a buffer • Goal : prove the exchange correct

  2. Auxiliary Predicates • Pushed H E iff 
 E is a multiset of elements, pushed in H • Popped H E iff 
 E is a multiset of elements, popped in H

  3. { Ap ↦ L ⋀ Pushed H s L [ < i ] ⋀ Popped H s ∅ } letrec produce(i : nat) = { if (i == n) then return ; else { S.push(Ap[i]); produce(i+1); } } { Ap ↦ L ⋀ Pushed H s L [ < n ] ⋀ Popped H s ∅ }

  4. { ∃ L, Ac ↦ L ⋀ Pushed H s ∅ ⋀ Popped H s L [ < i ] } letrec consume(i : nat) = { if (i == n) then return ; else { t ← S.pop(); if t == Some v 
 then { Ac[i] := v; consume(i+1); } else consume(i); } } { ∃ L, Ac ↦ L ⋀ Pushed H s ∅ ⋀ Popped H s L [ < n ] }

  5. No other threads 
 can interfere on S hide C stack ( h S ) in   � �     � �   � � produce(0) consume(0) � � � � � �   � �     � �

  6. { Ap ↦ L ⊕ Ac ↦ L ′ ⊕ h S } hide C stack ( h S ) in   � �     � �   � � produce(0) consume(0) � � � � � �   � �     � �

  7. { Ap ↦ L ⊕ Ac ↦ L ′ ⊕ h S } hide C stack ( h S ) in   { Ap ↦ L { Ac ↦ L ′ � �   ⋀ Pushed H s ∅ ⋀ Popped H s ∅ } ⋀ Pushed H s ∅ ⋀ Popped H s ∅ }   � �   � � produce(0) consume(0) � � � � � �   � �     � �

  8. { Ap ↦ L ⊕ Ac ↦ L ′ ⊕ h S } hide C stack ( h S ) in   { Ap ↦ L { Ac ↦ L ′ � �   ⋀ Pushed H s ∅ ⋀ Popped H s ∅ } ⋀ Pushed H s ∅ ⋀ Popped H s ∅ }   � �   � � produce(0) consume(0) � � � � { Ac ↦ L ′′ ⋀ 
 { Ap ↦ L ⋀ 
 � �   � �   Pushed H s ∅ ⋀ 
 Pushed H s L [ < n ] ⋀ 
   � � Popped H s ∅ } Popped H s L ′′ [<n] } These are the only changes 
 in the stack’s history

  9. { Ap ↦ L ⊕ Ac ↦ L ′ ⊕ h S } hide C stack ( h S ) in   { Ap ↦ L { Ac ↦ L ′ � �   ⋀ Pushed H s ∅ ⋀ Popped H s ∅ } ⋀ Pushed H s ∅ ⋀ Popped H s ∅ }   � �   � � produce(0) consume(0) � � � � { Ac ↦ L ′′ ⋀ 
 { Ap ↦ L ⋀ 
 � �   � �   Pushed H s ∅ ⋀ 
 Pushed H s L [ < n ] ⋀ 
   � � Popped H s ∅ } Popped H s L ′′ [<n] } { Ap ↦ L ⊕ Ac ↦ L ′′ ⊕ h S ′ ⋀ L = set L ′′ }

  10. Key insights • Subjectivity — reasoning with self and other • Histories • Deep Sharing

  11. Key insights • Subjectivity — reasoning with self and other • Histories — temporal specification via state • Deep Sharing

  12. Key insights • Subjectivity — reasoning with self and other • Histories — temporal specification via state • Deep Sharing

  13. Ramified data structures a b c d e

  14. In-place concurrent spanning tree construction x m l r mark the node x ... ... letrec span (x : ptr) : bool = { if x == null then return false; else b ← CAS(x->m, 0, 1); if b then (r l ,r r ) ← (span(x->l) || span(x->r)); if ¬r l then x->l := null; if ¬r r then x->r := null; return true; else return false; run in parallel for successors } prune redundant edges

  15. a b c d e

  16. a ✔ ✔ b c d e

  17. a ✔ ✔ ✗ b c ✗ ✔ ✔ d e

  18. a ✔ ✔ ✗ b c ✗ ✔ ✔ d e

  19. a ✔ ✔ b c d e

  20. a b c d e

  21. Why verifying span is difficult? The recursion scheme does not 
 follow the shape of the structure. a including b c is that } | P V Q | | t P d e V a a i s Q i | t t n h | c a b c l b c t u d i n g d e d e

  22. Assumptions for correctness letrec span (x : ptr) : bool = { if x == null then return false; else b ← CAS(x->m, 0, 1); if b then (r l ,r r ) ← (span(x->l) || span(x->r)); if ¬r l then x->l := null; if ¬r r then x->r := null; return true; else return false; } • The graph modified only by the commands of span • The initial call is done from a root node

  23. Graph Resource: State a b c d e shared state (heap)

  24. Graph Resource: State Auxiliary state 
 of all other threads a a b b c c d e Auxiliary state 
 of this thread

  25. Graph Resource: marking a node a b b c mark(b) a d e b c d e marked by this thread 
 (Guarantee)

  26. Graph Resource: marking a node marked by other thread 
 (Rely) a b c mark(b) T a d e b b c d e

  27. Graph Resource: pruning an edge a a p r u n e ( b - > r ) b c b c b b d e d e No other thread can do it!

  28. Specification for span { P } span(x) { Q }@C SpanTree

  29. Specification for span span(x) : span_tp ( x , C SpanTree , P , Q)

  30. Specification for span Definition span_tp (x : ptr) := {i (g1 : graph (joint i))}, STsep [SpanTree] ( fun s1 => i = s1 ⋀ (x == null ⋁ x ∈ dom (joint s1)), fun (r : bool) s2 => exists g2 : graph (joint s2), subgraph g1 g2 ⋀ if r then x != null ⋀ exists (t : set ptr), self s2 = self i ⊕ t ⋀ tree g2 x t ⋀ maximal g2 t ⋀ front g1 t (self s2 ⊕ other s2) else (x == null ⋁ mark g2 x) ⋀ self s2 = self i).

  31. Specification for span concurrent resource Definition span_tp (x : ptr) := {i (g1 : graph (joint i))}, STsep [SpanTree] ( fun s1 => i = s1 ⋀ (x == null ⋁ x ∈ dom (joint s1)), fun (r : bool) s2 => exists g2 : graph (joint s2), subgraph g1 g2 ⋀ if r then x != null ⋀ exists (t : set ptr), self s2 = self i ⊕ t ⋀ tree g2 x t ⋀ maximal g2 t ⋀ front g1 t (self s2 ⊕ other s2) else (x == null ⋁ mark g2 x) ⋀ self s2 = self i).

  32. Specification for span precondition Definition span_tp (x : ptr) := {i (g1 : graph (joint i))}, STsep [SpanTree] ( fun s1 => i = s1 ⋀ (x == null ⋁ x ∈ dom (joint s1)), fun (r : bool) s2 => exists g2 : graph (joint s2), subgraph g1 g2 ⋀ if r then x != null ⋀ exists (t : set ptr), self s2 = self i ⊕ t ⋀ tree g2 x t ⋀ maximal g2 t ⋀ front g1 t (self s2 ⊕ other s2) else (x == null ⋁ mark g2 x) ⋀ self s2 = self i).

  33. Specification for span Definition span_tp (x : ptr) := {i (g1 : graph (joint i))}, STsep [SpanTree] ( fun s1 => i = s1 ⋀ (x == null ⋁ x ∈ dom (joint s1)), fun (r : bool) s2 => exists g2 : graph (joint s2), subgraph g1 g2 ⋀ if r then x != null ⋀ exists (t : set ptr), self s2 = self i ⊕ t ⋀ tree g2 x t ⋀ maximal g2 t ⋀ front g1 t (self s2 ⊕ other s2) else (x == null ⋁ mark g2 x) ⋀ self s2 = self i). postcondition

  34. Specification for span Definition span_tp (x : ptr) := {i (g1 : graph (joint i))}, STsep [SpanTree] ( fun s1 => i = s1 ⋀ (x == null ⋁ x ∈ dom (joint s1)), fun (r : bool) s2 => exists g2 : graph (joint s2), subgraph g1 g2 ⋀ if r then x != null ⋀ exists (t : set ptr), self s2 = self i ⊕ t ⋀ logical variables tree g2 x t ⋀ maximal g2 t ⋀ front g1 t (self s2 ⊕ other s2) else (x == null ⋁ mark g2 x) ⋀ self s2 = self i).

  35. Specification for span Definition span_tp (x : ptr) := {i (g1 : graph (joint i))}, STsep [SpanTree] ( fun s1 => i = s1 ⋀ (x == null ⋁ x ∈ dom (joint s1)), fun (r : bool) s2 => exists g2 : graph (joint s2), subgraph g1 g2 ⋀ if r then x != null ⋀ exists (t : set ptr), self s2 = self i ⊕ t ⋀ tree g2 x t ⋀ maximal g2 t ⋀ front g1 t (self s2 ⊕ other s2) else (x == null ⋁ mark g2 x) ⋀ self s2 = self i).

  36. Specification for span Definition span_tp (x : ptr) := {i (g1 : graph (joint i))}, STsep [SpanTree] ( fun s1 => i = s1 ⋀ (x == null ⋁ x ∈ dom (joint s1)), fun (r : bool) s2 => exists g2 : graph (joint s2), subgraph g1 g2 ⋀ if r then x != null ⋀ exists (t : set ptr), self s2 = self i ⊕ t ⋀ tree g2 x t ⋀ maximal g2 t ⋀ front g1 t (self s2 ⊕ other s2) else (x == null ⋁ mark g2 x) ⋀ self s2 = self i).

  37. Specification for span Definition span_tp (x : ptr) := {i (g1 : graph (joint i))}, STsep [SpanTree] ( fun s1 => i = s1 ⋀ (x == null ⋁ x ∈ dom (joint s1)), fun (r : bool) s2 => exists g2 : graph (joint s2), a subgraph g1 g2 ⋀ if r then x != null ⋀ exists (t : set ptr), self s2 = self i ⊕ t ⋀ b x c t tree g2 x t ⋀ maximal g2 t ⋀ front g1 t (self s2 ⊕ other s2) d e else (x == null ⋁ mark g2 x) ⋀ self s2 = self i).

  38. Specification for span Definition span_tp (x : ptr) := {i (g1 : graph (joint i))}, STsep [SpanTree] ( fun s1 => i = s1 ⋀ (x == null ⋁ x ∈ dom (joint s1)), fun (r : bool) s2 => exists g2 : graph (joint s2), a subgraph g1 g2 ⋀ if r then x != null ⋀ exists (t : set ptr), self s2 = self i ⊕ t ⋀ b x c t tree g2 x t ⋀ maximal g2 t ⋀ front g1 t (self s2 ⊕ other s2) d e else (x == null ⋁ mark g2 x) ⋀ self s2 = self i).

  39. Specification for span Definition span_tp (x : ptr) := {i (g1 : graph (joint i))}, STsep [SpanTree] ( fun s1 => i = s1 ⋀ (x == null ⋁ x ∈ dom (joint s1)), fun (r : bool) s2 => exists g2 : graph (joint s2), a subgraph g1 g2 ⋀ if r then x != null ⋀ exists (t : set ptr), self s2 = self i ⊕ t ⋀ b x c tree g2 x t ⋀ maximal g2 t ⋀ front g1 t (self s2 ⊕ other s2) d e else (x == null ⋁ mark g2 x) ⋀ self s2 = self i).

  40. Specification for span Definition span_tp (x : ptr) := {i (g1 : graph (joint i))}, STsep [SpanTree] ( fun s1 => i = s1 ⋀ (x == null ⋁ x ∈ dom (joint s1)), fun (r : bool) s2 => exists g2 : graph (joint s2), a subgraph g1 g2 ⋀ if r then x != null ⋀ exists (t : set ptr), self s2 = self i ⊕ t ⋀ b x c tree g2 x t ⋀ maximal g2 t ⋀ front g1 t (self s2 ⊕ other s2) front g1 t (self s2 ⊕ other s2) d e else (x == null ⋁ mark g2 x) ⋀ self s2 = self i). Open world assumption (assuming other-interference)

  41. Cancelling the interference a b x c d e front g1 t (self s2 ⊕ other s2)

  42. Cancelling the interference a b x c d e front g1 t (self s2 ⊕ other s2) hide C SpanTree (h 1 ) in { span( a ) } donated local heap no other threads at the end

Recommend


More recommend