Presentation is loading. Please wait.

Presentation is loading. Please wait.

Modular verification of multithreaded shared-memory programs

Similar presentations


Presentation on theme: "Modular verification of multithreaded shared-memory programs"— Presentation transcript:

1 Modular verification of multithreaded shared-memory programs
Alexander Malkis

2 Second assault on Jerusalem: the crusaders repulsed
Second assault on Jerusalem: the crusaders repulsed. The crusaders leave the battlefield disappointed after 12 hours of fighting. The First Crusade (1096–1099). Gustav Doré (1832 – 1883). Completed 1877.

3 Owicki-Gries Rely-guarantee reasoning Thread-modular model checking Cartesian abstraction Thread simplification Refinement

4 int x=0; proctype Inc() { do :: atomic{ x<200 -> x=x+1 } od } proctype Dec() { do :: atomic{ x>0 -> x=x-1 } od } proctype Reset() { do :: x==200 -> x=0 od } proctype Check() { assert 0<=x && x<= } init { byte k=0; run Check(); do :: k<3 -> run Inc(); run Dec(); run Reset(); k++ od } State-vector 60 byte, depth reached 3435, errors: 0 ... pan: elapsed time 0 seconds

5 6 threads: s, 0.6 M 9 threads: s, 0.8 M 12 threads: s, 1.2 M 15 threads: s, 2 M 18 threads: s, 3.3 M 21 threads: s, 6.7 M 24 threads: s, 14 M 27 threads: s, 30 M 30 threads: s, 65 M 33 threads: s, 138 M 36 threads: s, 297 M 39 threads: 67 s, 617 M 42 threads: 151 s, 1309 M 45 threads: 339 s, 2769 M 48 threads: out of space

6 Owicki-Gries succeeds
{x=0} x≔x+1 ║ x≔x+2 {x=3} {x=0} {...} ║ {...} x≔x+1 ║ x≔x+2 {...} ║ {...} {x=3}

7 Owicki-Gries succeeds
{x=0} x≔x+1 ║ x≔x+2 {x=3} {x=0} {x=0 v x=2} ║ {x=0 v x=1} x≔x+1 ║ x≔x+2 {x=1 v x=3} ║ {x=2 v x=3} {x=3}

8 Owicki-Gries fails {x=0} x≔x+1 ║ x≔x+1 {x=2}
{x=0} { x=0 v ...} ║ { x=0 v ...} x≔x+1 ║ x≔x+1 { x=1 v ...} ║ { x=1 v ...} { x=1 v ...}

9 Owicki-Gries fails {x=0} x≔x+1 ║ x≔x+1 {x=2}
{x=0} { x=0 v x=1 v ...} ║ { x=0 v x=1 v ...} x≔x+1 ║ x≔x+1 { x=1 v x=2 v ...} ║ { x=1 v x=2 v ...} { x=1 v x=2 v ...}

10 Owicki-Gries fails {x=0} x≔x+1 ║ x≔x+1 {x=2}
{x=0} { x=0 v x=1 v x=2 v ...} ║ { x=0 v x=1 v x=2 v ...} x≔x+1 ║ x≔x+1 { x=1 v x=2 v x=3 v ...} ║ { x=1 v x=2 v x=3 v ...} { x=1 v x=2 v x=3 v ...}

11 Owicki-Gries: auxiliary variables
{x=0} x≔x+1 ║ x≔x+1 {x=2} {x=0} a≔0 {x=0 ∧ a=0} (x,a)≔(x+1,1) ║ (x,a)≔(x+1,2) {?}

12 Owicki-Gries: auxiliary variables
{x=0} x≔x+1 ║ x≔x+1 {x=2} {x=0} a≔0 {x=0 ∧ a=0} {(x=0∧a=0) v (x=1∧a=2)} ║ {(x=0∧a=0) v (x=1∧a=1)} (x,a)≔(x+1,1) ║ (x,a)≔(x+1,2) {(x=1∧a=1) v (x=2∧a=1) v ║ {(x=1∧a=2) v (x=2∧a=2) v v (x=2∧a=2)} ║ v (x=2∧a=1)} {x=2 ∧ (a=1 v a=2)} {x=2}

13 Auxiliary assignments must terminate
{true} aux≔1/0; skip; {false} {true} aux≔array[index_out_of_bounds]; skip; {false} {true} skip; {false}

14 Owicki-Gries: completeness
State = Mem ⨯ PC1 ⨯ … ⨯ PCn NewState = NewMem ⨯ PC1 ⨯ … ⨯ PCn {x=0} p1≔A; p2≔C {x=0 ∧ p1=A ∧ p2=C} A: {p1=A∧ ((x=0∧p2=C)v(x=1∧p2=D))} (x,p1)≔(x+1,B) B: {p1=B∧ ((x=1∧p2=C)v(x=2∧p2=D))} C: {p2=C∧ ((x=0∧p1=A)v(x=1∧p1=B))} (x,p2)≔(x+1,D) D: {p2=D∧ ((x=1∧p1=A)v(x=2∧p1=B))} {x=2 ∧ p1=B ∧ p2=D} {x=2}

15 Rely-Guarantee T1║guar2 ≤ guar1 guar1║T2 ≤ guar2 ∀i: posti ⇒ post
∧ (rely v ∃k≠i: guark) ⇒ relyi ∧ guari ⇒ guar ∧ Ti sat (pre, relyi, guari, posti) ──────────────────────── T1║...║Tn sat (pre, rely, guar, post)

16 Rely-Guarantee succeeds
“A: x≔x+1; B:” sat (x=0, x'=x v (x=0∧x'=2) v (x=1∧x'=3), x'=x v (x=0∧x'=1) v (x=2∧x'=3), x=1 v x=3) “C: x≔x+2; D:” sat (x=0, x'=x v (x=0∧x'=1) v (x=2∧x'=3), x'=x v (x=0∧x'=2) v (x=1∧x'=3), x=2 v x=3) “A: x≔x+1; B: ║ C: x≔x+2; D:” sat (x=0, x'=x, x'=x v x'=x+1 v x'=x+2, x=3) Also allowed: rigid vars (not occurring in the program) Required: reflexive rely, reflexive guarantee P sat (pre,rely,guarantee,post) means: For all valuations of rigid variables v0: (P starts in a state satisfying pre and all environment transitions satisfy rely) =>(all transitions of P satisfy guarantee and the final state satisfies post) ∀i: (rely or ∃j≠i: guar_j) => rely_i ∀i: guar_i => guar ∀i: Pi sat (pre,rely_i,guar_i,post) P1║...║Pn sat (pre,rely,guar,post)

17 Rely-guarantee fails “A: x≔x+1; B:” sat (x=0, x'=x,
x'=x v (x=0∧x'=1), x=1) “C: x≔x+1; D:” sat (x=0, x'=x, x'=x v (x=0∧x'=1), x=1)

18 Rely-guarantee fails “A: x≔x+1; B:” sat (x=0, x'=x v (x=0∧x'=1),
x'=x v (x=0∧x'=1) v (x=1∧x'=2), x=1 v x=2) “C: x≔x+1; D:” sat (x=0, x'=x v (x=0∧x'=1), x'=x v (x=0∧x'=1) v (x=1∧x'=2), x=1 v x=2)

19 Rely-guarantee fails “A: x≔x+1; B:” sat (x=0, x'=x v (x=0∧x'=1) v (x=1∧x'=2), x'=x v (x=0∧x'=1) v (x=1∧x'=2) v (x=2∧x'=3), x∊{1,2,3}) “C: x≔x+1; D:” sat (x=0, x'=x v (x=0∧x'=1) v (x=1∧x'=2),

20 Rely-guarantee fails “A: x≔x+1; B:” sat (x=0, x'=x v 1≤x'=x+1,
x'=x v 1≤x'=x+1, x≥1) “C: x≔x+1; D:” sat (x=0, x'=x v 1≤x'=x+1, “A: x≔x+1; B: ║ C: x≔x+1; D:” sat (x=0, x'=x v 1≤x'=x+1, x'=x v 1≤x'=x+1, x≥1) Also allows auxiliary variables. Even complete with auxiliary variables.

21 Thread-Modular model checking succeeds
{x=0} A: x≔x+1 ║ C: x≔x+2 B: ║ D: {x=3} R1={...}, R2={...} G1={...}, G2={...}

22 Thread-Modular model checking succeeds
{x=0} A: x≔x+1 ║ C: x≔x+2 B: ║ D: {x=3} R1={0A, ...}, R2={0C, ...} G1={...}, G2={...}

23 Thread-Modular model checking succeeds
{x=0} A: x≔x+1 ║ C: x≔x+2 B: ║ D: {x=3} R1={0A, 1B, ...}, R2={0C, 2D, ...} G1={0►1, ...}, G2={0►2, ...}

24 Thread-Modular model checking succeeds
{x=0} A: x≔x+1 ║ C: x≔x+2 B: ║ D: {x=3} R1={0A, 1B, 2A, ...}, R2={0C, 2D, 1C, ...} G1={0►1, ...}, G2={0►2, ...}

25 Thread-Modular model checking succeeds
{x=0} A: x≔x+1 ║ C: x≔x+2 B: ║ D: {x=3} R1={0A, 1B, 2A, 3B}, R2={0C, 2D, 1C, 3D} G1={0►1, 2►3}, G2={0►2, 1►3}

26 Thread-Modular model checking fails
{x=0} A: x≔x+1 ║ C: x≔x+1 B: ║ D: {x=2} R1= R2= {0A, ...}, {0C,...} G1={...}, G2={...}

27 Thread-Modular model checking fails
{x=0} A: x≔x+1 ║ C: x≔x+1 B: ║ D: {x=2} R1= R2= {0A,1B, ...}, {0C,1D, ...} G1={0►1, ...}, G2={0►1, ...}

28 Thread-Modular model checking fails
{x=0} A: x≔x+1 ║ C: x≔x+1 B: ║ D: {x=2} R1= R2= {0A,1B,1A, ...}, {0C,1D,1C, ...} G1={0►1, ...}, G2={0►1, ...}

29 Thread-Modular model checking fails
{x=0} A: x≔x+1 ║ C: x≔x+1 B: ║ D: {x=2} R1= R2= {0A,1B,1A,2B, ...}, {0C,1D,1C,2D, ...} G1={0►1, 1►2, ...}, G2={0►1, 1►2, ...}

30 Thread-Modular model checking fails
{x=0} A: x≔x+1 ║ C: x≔x+1 B: ║ D: {x=2} R1= R2= {0A,1B,1A,2B,2A,3B,...}, {0C,1D,1C,2D,2C,3D,...} G1={0►1, 1►2, 2►3,...}, G2={0►1, 1►2, 2►3,...}

31 Multithreaded Cartesian abstraction succeeds
{x=0} A: x≔x+1 ║ C: x≔x+2 B: ║ D: {x=3} {0}x{A}x{C} {0}x{A}x{C} ∪ {1}x{B}x{C} ∪ {2}x{A}x{D} {0}x{A}x{C} ∪ {1}x{B}x{C} ∪ {2}x{A}x{D} ∪ {3}x{B}x{D}

32 Multithreaded Cartesian abstraction fails
{x=0} A: x≔x+1 ║ C: x≔x+1 B: ║ D: {x=2} {0}x{A}x{C} {0}x{A}x{C} ∪ {1} x ρ({B}x{C}∪{A}x{D})

33 Multithreaded Cartesian abstraction fails
{x=0} A: x≔x+1 ║ C: x≔x+1 B: ║ D: {x=2} {0}x{A}x{C} {0}x{A}x{C} ∪ {1}x{A,B}x{C,D} {0}x{A}x{C} ∪ {1}x{A,B}x{C,D} ∪ {2} x ρ({B}x{C,D}∪{A,B}x{D})

34 Multithreaded Cartesian abstraction fails
{x=0} A: x≔x+1 ║ C: x≔x+1 B: ║ D: {x=2} {0}x{A}x{C} {0}x{A}x{C} ∪ {1}x{A,B}x{C,D} {0}x{A}x{C} ∪ {1}x{A,B}x{C,D} ∪ {2}x{A,B}x{C,D} {0}x{A}x{C} ∪ {1}x{A,B}x{C,D} ∪ {2}x{A,B}x{C,D} ∪ {3} x ρ({B}x{C,D}∪{A,B}x{D})

35 Multithreaded Cartesian abstraction fails
{x=0} A: x≔x+1 ║ C: x≔x+1 B: ║ D: {x=2} {0}x{A}x{C} {0}x{A}x{C} ∪ {1}x{A,B}x{C,D} {0}x{A}x{C} ∪ {1}x{A,B}x{C,D} ∪ {2}x{A,B}x{C,D} {0}x{A}x{C} ∪ {1}x{A,B}x{C,D} ∪ {2}x{A,B}x{C,D} ∪ {3}x{A,B}x{C,D}

36 Without auxiliary / rigid variables: common precision
∃ Owicki-Gries proof ⇔ ∃ rely-guarantee proof ⇔ ∃ thread-modular proof ⇔ ∃ multithreaded Cartesian proof Finite-state: polynomial time

37 Abstract Threads T1 || … || Tn ⇑ A1 || … || An T1 … Tn ⊓ … ⊓ A1 … An
⊓ … ⊓ A1 … An T1 … T8 are concrete threads, 1 unload, 7 workers, specs by asserts in code A1 … A8 are smaller abstract threads, 1 unload, 7 workers, specs by asserts in code Check: A1 || … || A8 is correct and T1 abstracted by A1, …, T8 abstracted by A8 Then: T1 || … || T8 is correct

38 Abstract Threads example
Thread A Thread B g>0 Interleaving Spec of a thread is a thread Arbitrary control flow in the spec Verify each thread separately Free (not) to encode environment assumption into spec of a thread Bounded correctness transfers Property given by assertions More automation than in thr.-mod. Verif.: no need for manual simulation relation, for finite local state space semiautomatic methods available! Infinite local state removed! 38

39 Abstract Threads: Phased Execution
((g0,g1,g2,g3), (g'0,g'1,g'2), (l0,l1,l2,l3)) g0l0 g'0l1 g1l1 g'1l2 g2l2 g'2l3 g3l3 39

40 Abstract Threads: Abstraction
40

41 Abstract threads: Conformance Checker
State of conformance checker: (l,F) States = Local ⨯ ℘(Local#) Start = Init ⨯ {Init#} Error = Local ⨯ {Ø} U {(l,F) | W(l)⊈W#(F)} 41

42 Abstract Threads: Conformance Checker Coding
Replace non-assert st by assert F≠Ø; assume ∀l#∈F: (g,l#)∉Wrong#; st; F ≔ {m' | ∃m∈F: (stored_g,m) →# (g,m')}; havoc g; stored_g≔g; Replace “assert φ” by assert ¬φ ⇒ ∃l#∈F: (g,l#)∈Wrong# 42

43 Battery Class Driver 2 code files, 1 header, 3292 C code lines
Promela: 141 lines, 24 states / thread 1 unload, 1 worker: <0.01s 1 unload, 2 workers: <0.08s 1 unload, 3 workers: 1s 1 unload, 4 workers: 8s 1 unload, 5 workers: 54s 1 unload, 6 workers: 242s 1 unload, 7 workers: 929s Exponential expected: 2.2^n. WANT: more threads, less time. Solution for a fixed tool: reduce thread size. Book with sections. Replace a section by its abstract summary. Make sure: Summaries make sense together. A summary correctly abstracts a section.

44 Abstract Threads: Battery Class Driver
Boogie: 30 s. SPIN:

45 Owicki-Gries Rely-guarantee reasoning Thread-modular model checking Cartesian abstraction Thread simplification Refinement

46


Download ppt "Modular verification of multithreaded shared-memory programs"

Similar presentations


Ads by Google