rgsep action inference
play

RGSep action inference Viktor Vafeiadis Microsoft Research - PowerPoint PPT Presentation

RGSep action inference Viktor Vafeiadis Microsoft Research Cambridge/ University of Cambridge Michael & Scott non-blocking queue head tail null X 1 2 3 4 typedef struct Node_s *Node; struct Queue_s *Q; struct Node_s { init() { int


  1. RGSep action inference Viktor Vafeiadis Microsoft Research Cambridge/ University of Cambridge

  2. Michael & Scott non-blocking queue head tail null X 1 2 3 4 typedef struct Node_s *Node; struct Queue_s *Q; struct Node_s { init() { int val; n = new Node(); Node next; n → next = null; } Q = new Queue(); Q → head = node; struct Queue_s { Q → tail = node; Node head; } Node tail; }

  3. A slight complication... The tail pointer can lag behind by one node: head tail null X 1 2 3 Except when the queue is empty: head tail null Y X

  4. Enqueue & dequeue Don’t read the code ! dequeue () { enqueue(v) { while (true) { m = new Node(); m → val = v; h = Q → head; m → next = null; t = Q → tail; while (true) { n = h → next; t = Q → tail; if (Q → tail ≠ t) continue ; n = tail → next; if (h == t) { if (Q → tail ≠ tail) continue ; if (n == null) if (next == null) { return EMPTY; if (CAS(&t → next,n,m)) CAS(&Q → tail,t,n); break; } else { } else { if (CAS(&Q → head,h,n)) CAS(&Q → tail,t,n); return n → val; } } } } CAS(&Q → tail,t,n); } }

  5. Verification challenge Functional correctness: Every method executes ‘atomically’ and obeys a high-level specification VMCAI ’09 work in progress Liveness properties, e.g. lock-freedom: At all times, some outstanding method call is guaranteed to terminate. POPL ’09 But first, do shape analysis to: (1) Find data structure invariants this talk (2) Prove memory safety

  6. RGSep Combining rely-guarantee and separation logic

  7. Whence RGSep? Separation logic:  Good at describing dynamically allocated data structures head tail null ∃ h t. Q ↦ head:h,tail:t ∗ lseg(h,t) ∗ t ↦ next:null Rely-guarantee:  Good at reasoning about concurrency  Describes interference between threads: how the state evolves

  8. Local & shared assertions Logically divide the state into:  Local: only one thread can access it  Shared: any thread can access it. RGSep assertions: p, q ::= (P local ¦ P Shared ) | p 1 ∨ p 2 normal separation logic assertions (about the local & | ∃ x. p shared state respectively)

  9. Rely-guarantee specifications Rely: interference caused by environment; Describes how the environment is allowed to change the shared precondition state R,G ⊢ RGSep {p} cmd {q} Guarantee: postcondition interference caused by the program. Describes how the program is allowed to change the shared state.

  10. RGSep actions (pre-/postcondition pairs)  Summarize the shared state updates head tail head tail Enqueue null null A B A head tail head tail Dequeue A B A B head tail head tail Advance tail pointer A B A B

  11. RGSep actions (pre-/postcondition & context)  Summarize the shared state updates head tail head tail Enqueue null null A B A head tail head tail Dequeue A B A B head tail head tail Advance tail pointer A B A B

  12. The actions of enqueue & dequeue enqueue(v) { dequeue () { m = new Node(); while (true) { m → val = v; Local h = Q → head; m → next = null; updates t = Q → tail; while (true) { n = h → next; t = Q → tail; if (Q → tail ≠ t) continue ; n = tail → next; if (h == t) { if (Q → tail ≠ tail) continue ; if (n == null) if (next == null) { return EMPTY; if (CAS(&t → next,n,m)) ENQUEUE CAS(&Q → tail,t,n); ADV. TAIL break; } else { } else { if (CAS(&Q → head,h,n)) DEQUEUE CAS(&Q → tail,t,n); ADV. TAIL return n → val; } } } } } CAS(&Q → tail,t,n); ADV. TAIL }

  13. The semantics of actions precondition postcondition [[R|P ↝ Q]] ≝ {(s ⊎ s ctx , s’ ⊎ s ctx ) | ∃ I. [[P]] I (s) ∧ [[Q]] I (s’) context ∧ [[R ∗ true]] I (s ctx ) } R & G are sets of such actions: [[{a 1 ,...a n }]] ≝ ([[a 1 ]] ∪ ... ∪ [[a n ]])*

  14. Action Inference

  15. The action inference problem  Given cmd, R, p: find G, q s.t. R, G ⊢ RGSep {p} cmd {q}. Preferably, the strongest G and q  Top-level programs: R = ∅ and p = true.  Libraries; the most general client: init(); ‖ ? { if (?) enqueue(?) else if (?) dequeue() else length() }

  16. (Must)-Subtraction a.k.a. entailment with frame inference S UBTRACT (P, Q, xs) returns R such that [[P]] I (s) ⇒ ∃ s 1 s 2 vs. s=s 1 ⊎ s 2 ∧ [[Q]] I[xs → vs] (s 1 ) ∧ [[R]] I[xs → vs] (s 2 ), or fails if no such an R exists, or because if cannot find it. Used to calculate postcondition of normal commands. Given precondition P & command with spec {P o } _ {Q o }, the postcondition is: S UBTRACT (P, P o ) ∗ Q o

  17. May-Subtraction M AY -S UBTRACT (P, Q, R) returns R’ such that [[P]] I (s 1 ⊎ s 2 ) ∧ [[Q]] I (s 1 ) ∧ [[R ∗ true]] I (s 2 ) ⇒ [[R’]] I (s 2 )  Generalization of septraction (existential magic wand)  Used to calculate postcondition after interference. Given precondition P and an action (R o | P o ↝ Q o ), the postcondition is: M AY -S UBTRACT (P, P o , R o ) ∗ Q o

  18. Examples S UBTRACT (a ↦ 3 ∗ b ↦ 4, a ↦ x, {}) = Error! S UBTRACT (a ↦ 3 ∗ b ↦ 4, a ↦ x, {x}) = b ↦ 4 ∗ (x = 3) M AY -S UBTRACT (a ↦ 3, a ↦ x, emp) = (x = 3) M AY -S UBTRACT (a ↦ 3, emp, a ↦ x) = a ↦ 3 ∗ (x = 3) M AY -S UBTRACT (a ↦ 3 ∗ b ↦ 4, x ↦ y, emp) = b ↦ 4 ∗ (x = a) ∗ (y = 3) ∨ a ↦ 3 ∗ (x = b) ∗ (y = 4)

  19. Stabilization  Calculate the e fg ect of interference on an assertion: overapproximate P; Rely* repeat P old := P; for each R i |P i ↝ Q i in Rely do P := P ∨ M AY -S UBTRACT (P old , P i , R i ) ∗ Q i ; until (P = P old )

  20. Symbolic execution of memory reads S YMB -E XEC (Rely, p 1 ∨ p 2 , x=*E) ≝ // Do the obvious case split... R, G 1 ⊢ {p 1 } C {q 1 } (G 1 , q 1 ) := S YMB -E XEC (Rely, p 1 , x=*E); R, G 2 ⊢ {p 2 } C {q 2 } (G 2 , q 2 ) := S YMB -E XEC (Rely, p 2 , x=*E); R, G 1 ∪ G 2 ⊢ {p 1 ∨ p 2 } C {q 1 ∨ q 2 } return (G 1 ∪ G 2 , q 1 ∨ q 2 ) { ∃ α . E ↦ α ∗ R} S YMB -E XEC (Rely, (P L ¦ P S ), x=*E) ≝ x=*E // Is it a local read? { ∃ αβ . E[ β /x] ↦ α ∗ x= α ∗ R[ β /x]} if S UBTRACT( P L , ∃ α . E ↦ α ) = R L then return ( ∅ , ( ∃ αβ . x= α ∗ E[ β /x] ↦ α ∗ R L [ β /x] ¦ P S [ β /x])) // Is it a shared read? else if S UBTRACT( P S , ∃ α . E ↦ α ) = R S then return ( ∅ , ( ∃ αβ . x= α ∗ E[ β /x] ↦ α ∗ P L [ β /x] ¦ R S [ β /x])) else Verification-Error

  21. Symbolic execution of memory writes S YMB -E XEC (Rely, (P L ¦ P S ), *E=E’) ≝ { ∃ α . E ↦ α ∗ R} *E=E’ {E ↦ E’ ∗ R} // Is it a local write? if S UBTRACT( P L , ∃ α . E ↦ α ) = R L then return ( ∅ , (E ↦ E’ ∗ R L ¦ P S )) // Is it a shared write? else if S UBTRACT( P S , ∃ α . E ↦ α ) = R S then // Anything in the local state reachable from E’ becomes shared (P L2S , P L ) := R EACHABLE- S PLIT (P L , E ↦ E’); act := (R S | E ↦ α ↝ E ↦ E’ ∗ P L2S ); q := (P L ¦ E ↦ E’ ∗ P L2S ∗ R S ); // Abstract the action & return Transfer of ownership return ({A-A BS (act)}, q) Local to shared else Verification-Error

  22. Dealing with the parallel composition R ∪ G , G ⊢ {p} cmd {q} R, G ⊢ {p} cmd ∥ cmd {q} Fixed point calculation:  Start with G = ∅ . Symbolically execute cmd and get new G’.  Extend G with G’ and repeat until G’=G.

  23. Action abstraction Abstraction. Given an action (C | P ↝ Q), return (C’ | P’ ↝ Q’) such that [[C | P ↝ Q]] ⊆ [[C’ | P’ ↝ Q’]].  Replace local variables with fresh logical variables.  Abstract C, P, Q separately.  For locking and unlocking actions, let C’=emp.

  24. Initial experiments Algorithm Iter Actions Time (s) Treiber stack 4 5 0.1 M&S two-lock queue 5 26 0.3 M&S non-blocking queue 5 10 1.7 DGLM non-blocking queue 5 12 2.2 Lock-coupling list 4 21 1.0 Too many Optimistic list 5 30 109.1 actions Lazy list 5 48 60.0 Vechev’s CAS list 3 9 24.7 Vechev’s DCAS list 2 6 0.3

  25. Lossless join on action sets  Given action sets X & Y, return Z s.t. [[Z]] = [[X ∪ Y]].  Don’t do Z=X ∪ Y, but try to find a Z with fewer elements. Approximation to inclusion. (C 1 |P 1 ↝ Q 1 ) ⊑ (C 2 |P 2 ↝ Q 2 )  Exists substitution σ of the logical variables such that P 1 = σ (P 2 ) and Q 1 = σ (Q 2 ) and C 1 ⊢ σ (C 2 ) ∗ true  If (C 1 |P 1 ↝ Q 1 ) ⊑ (C 2 |P 2 ↝ Q 2 ), then [[C 1 |P 1 ↝ Q 1 ]] ⊆ [[C 2 |P 2 ↝ Q 2 ]]. Lossless join. JOIN(A,{b}) ≝ if ∃ a ∊ A. b ⊑ a then A else {b} ∪ {a ∊ A|a ⋢ b} JOIN(A,{b 1 ,...,b n }) ≝ JOIN(...(JOIN(JOIN(A, {b 1 }),{b 2 })...),{b n })

  26. Experiments No join With lossless join Algorithm Iter Actions Time (s) Iter Actions Time (s) Treiber stack 4 5 0.1 4 2 0.1 M&S two-lock queue 5 26 0.3 5 12 0.3 M&S non-blocking queue 5 10 1.7 5 6 1.5 DGLM non-blocking queue 5 12 2.2 5 8 2.0 Lock-coupling list 4 21 1.0 3 10 0.8 Optimistic list 5 30 109.1 3 10 52.3 Lazy list 5 48 60.0 4 13 26.2 Vechev’s CAS list 3 9 24.7 3 5 8.8 Vechev’s DCAS list 2 6 0.3 3 4 0.3 Run action inference, finding data structure invariants & proving memory safety. Iter: number of iterations for finding the rely-guarantee specs of each thread. Actions: number of actions inferred.

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