vercors verification of concurrent systems
play

VERCORS: VERIFICATION OF CONCURRENT SYSTEMS MARIEKE HUISMAN - PowerPoint PPT Presentation

VERCORS: VERIFICATION OF CONCURRENT SYSTEMS MARIEKE HUISMAN UNIVERSITY OF TWENTE, NETHERLANDS OUTLINE OF THIS LECTURE How to ensure software quality? Classical program logic Separation logic The next challenge: concurrent


  1. EXAMPLES INTUITIONISTIC SEPARATION LOGIC s h f 0 h0 Suppose x is an object in the store, with x fields f and g g 1 x h1 h0 = [ s ( x.f ) : 0] h1 = [ s ( x.g ) : 1] p s, h | = p p s, h | = p x.f → 0 x.f → 0 à h0 ⊆ h h0 à h1 ⊆ h ( x.f → 0 ∨ x.g → 1) x.g → 1 h1 ⊆ h ( x.f → 0 ∨ x.g → 1) à h0 à h1 ⊆ h ( x.f → 0 ∨ x.g → 1) x.f → 0 à x.g → 1 h0 à h1 ⊆ h x.f → 0 à x.g → 1 à ( x.f → 0 ∨ x.g → 1) false x.f → 0 à x.f → 0 false x.f → 0 à true h0 ⊆ h x.f → 0 ∨ x.g → 1 h0 ⊆ h or h1 ⊆ h Verification of Concurrent Systems 19/06/2014 28

  2. EXAMPLE: CLASS BOX class Box { int cnts; requires this.cnts → X; requires this.cnts → _; ensures this.cnts → X ∧ result = X; ensures this.cnts → o; int get() { void set (int o) { return this.cnts; this.cnts = o; } return null; } requires P; } ensures Q; Compare with specifications in void m(..) { ... } classical Hoare logic alternative notation for requires true; { P } method m() { Q } ensures this.cnts == o; Verification of Concurrent Systems 19/06/2014 29

  3. ADVANTAGES OF SEPARATION LOGIC § Reasoning about programs with pointers § Two interpretations e.f → v § Field e.f contains value v § Permission to access field e.f A field can only be accessed or written if e.f → _ holds! § Implicit disjointness of parts of the heap allows reasoning about (absence) of aliasing x.f → _ à y.f → _ implicitly says that x and y are not aliases § Local reasoning § only reason about heap that is actually accessed by code fragment § rest of heap is implicitly unaffected: frame rule Verification of Concurrent Systems 19/06/2014 30

  4. UPDATES AND LOOKUP OF THE HEAP { e.f → _} e.f := v { e.f → v } { X = e ∧ X.f → Y } v := e.f { X.f → Y ∧ v = Y } where X and Y are logical variables § For simplicity v is typically assumed to be a simple (unqualified) expression § Any assignment e.f := e’.g can be split up in x := e’.g; e.f := x Logical variables needed to handle x := x.f Verification of Concurrent Systems 19/06/2014 31

  5. WHY IS THE LOGICAL VARIABLE NEEDED? { x.f → Y } x := x.f { x.f → Y ∧ x = Y } is not correct! f x f x f x f But this is: { X = e ∧ X.f → Y } v := e.f { X.f → Y ∧ v = Y } Verification of Concurrent Systems 19/06/2014 32

  6. FRAME RULE . { P } S { Q } { P à R } S { Q à R } where R does not contain any variable that is modified by S. Verification of Concurrent Systems 19/06/2014 33

  7. THE CHALLENGE OF POINTER PROGRAMS class C { method m() { c := new C; D f; d := new D; c.f → _ à c.g → _ D g; c.f := d; does not hold } c.g := d; update_x(c.f, 3); Empty frame class D { } int x := 0; } ensures d.x = v; method update_x(d, v) { d.x := v; } Verification of Concurrent Systems 19/06/2014 34

  8. ABSTRACT PREDICATES Matthew Parkinson Verification of Concurrent Systems 19/06/2014 35

  9. SPECIFYING DATA STRUCTURES § Abstract predicates represent and encapsulate state, with appropriate operations § Abstract predicates are scoped § Code verified in scope can use name and body § Code verified out of scope can only use name § Explicit open/close axiom to open definition of abstract predicate, provided it is in scope α ( x1, ..,xn ) = P in scope |- α (e1, .., en ) ⇒ P [ x1 := e1 ,.. xn := en ] ⇒ Verification of Concurrent Systems 19/06/2014 36

  10. class Node { int val; Node next; ABSTRACT PREDICATES ON LIST } § Predicate list § pred list ( i ) = ( i = null) ∨ ∃ Node j, int a. i. val → a à i. next → j à list j recognises list structure § Predicate list: § pred list ( ϵ , i ) = ( i = null) § pred list (( a. α ), i ) = ∃ Node j. i. val → a à i. next → j à list α j relates list content with abstract list value § Operations like append and reverse in specifications can be defined on abstract type Verification of Concurrent Systems 19/06/2014 37

  11. ABSTRACT PREDICATE ON TREES § tree i = ( i = null) ∨ ∃ Node j, k. i. left → j à i. right → k à tree j à tree k recognises tree structure right Is this a tree? left left left right right right YES NO right Verification of Concurrent Systems 19/06/2014 38

  12. CONCURRENCY: THE NEXT CHALLENGE Doug Lea Verification of Concurrent Systems 19/06/2014 39

  13. THE FUTURE OF COMPUTING IS MULTICORE Single core processors: The end of Moore’s law Multicore Cell Processor Solution: Multi-core processors Multiple threads of execution Coordination problem shifts from hardware to software Verification of Concurrent Systems 19/06/2014 40

  14. MULTIPLE THREADS CAUSE PROBLEMS § Order? § More threads? read v Possible consequences: errors such as data races caused lethal bugs as in Therac-25 write v shared memory Verification of Concurrent Systems 19/06/2014 41

  15. VERIFICATION OF MULTITHREADED PROGRAMS Floyd - Hoare Dijkstra Concurrency (multithreading) Krakatoa Owicki - Gries O’Hearn VerCors Reliability of Concurrent and Distributed Software W o r k s h o : p 6 -‑ 9 M a y 2 0 1 4 , L e i d e n , t h e N e t h e r l a n d s Scientific • Marieke Huisman, U Twente Organizers • Einar Johnsen, UiO Oslo The Lorentz Center is an international center in the sciences. Its aim is to organize workshops for scientists in an atmosphere that fosters collaborative work, discussions and interactions. For registration see: www.lorentzcenter.nl Poster design: SuperNova Studios . NL 2004 Chalice separation logic Jones Verifast Verification of Concurrent Systems 19/06/2014 42

  16. OUR APPROACH Verification of Concurrent Systems 19/06/2014 43

  17. SPECIFICATIONS IN A CONCURRENT SETTING Any other thread requires true might invalidate this! ensures x is the last element in the list void addToList(Elem x) { ‘x is in the list’ // code cannot even be guaranteed! } x Except when no other thread can update the list Verification of Concurrent Systems 19/06/2014 44

  18. SOME HISTORY: REASONING ABOUT THREADS Susan Owicki Verification of Concurrent Systems 19/06/2014 45

  19. OWICKI-GRIES METHOD (1975) § For each thread: give a complete proof outline § Verify each thread w.r.t. the proof outline § For each annotation in the proof outline, show that it cannot be invalidated by any other thread: interference freedom David Gries Verification of Concurrent Systems 19/06/2014 46

  20. EXAMPLE OWICKI-GRIES {x = 0 ∧ y = 0}x := x + 1; x := x + 1 || y := y + 1; y := y + 1 {x = 2 ∧ y = 2} Proven correct by proving correctness of following: § proof outlines § {x = 0} x := x + 1 {x = 1} x := x + 1 {x = 2} § {y = 0} y := y + 1 {y = 1} y := y + 1 {y = 2} § interference freedom 2 x 2 x 3 proof obligations!! § {x = i ∧ y = j }y := y + 1 {x = i } (for i = 0, 1, 2, j = 0,1) § {x = j ∧ y = i }x := x + 1 {y = i } (for i = 0, 1, 2, j = 0,1) Verification of Concurrent Systems 19/06/2014 47

  21. DRAWBACKS OWICKI-GRIES § Number of proof obligations easily blows up § Non-compositional § Proof outlines need to be complete: annotations after each atomic step § Sometimes weakening of annotations necessary to be able to prove interference freeness Verification of Concurrent Systems 19/06/2014 48

  22. EXAMPLE WEAKENING OF ASSERTIONS How to prove correctness of {x = 0} x := x + 1 || x := x + 2 {x = 3} (assuming complete assignments are atomic) Following proof outlines need to be proven correct and free of interference § {x = 0 ∨ x = 2} x := x + 1 {x = 1 ∨ x = 3} § {x = 0 ∨ x = 1} x := x + 2 {x = 2 ∨ x = 3} Verification of Concurrent Systems 19/06/2014 49

  23. ALTERNATIVE APPROACH: WITH GHOST CODE {x = a + b & a == 0 & b == 0} {x == a + b & a == 0} || {x == a + b & b == 0} <x := x + 1;> || <x := x + 2;> <a := 1;> // ghost || <b :=2;> //ghost {x == a + b & a == 1} || {x == a + b & b == 2} {x == a + b & a == 1 & b == 2} {x == 3} Verification of Concurrent Systems 19/06/2014 50

  24. RELY-GUARANTEE METHOD § Jones (1980) § Compositional § For each thread, specify § what it assumes from other threads § what it guarantees to other threads rely ∨ guar1 ⇒ rely2 Rely: what transitions may rely ∨ guar2 ⇒ rely1 other threads make guar1 ∨ guar2 ⇒ guar Guarantee: what transitions 〈 relyi, guari 〉 : { Pi } Si { Qi }, i = 1,2 may current thread make 〈 rely, guar 〉 : { P } S1 || S2 { Q } Verification of Concurrent Systems 19/06/2014 51

  25. AVOIDING DATA RACES John Boyland Verification of Concurrent Systems 19/06/2014 52

  26. RECIPE FOR REASONING ABOUT JAVA § Separation logic for sequential Java (Parkinson) § Concurrent Separation Logic (O’Hearn) § Permissions (Boyland) Permission-based Separation Logic for Java Verification of Concurrent Systems 19/06/2014 53

  27. JOHN REYNOLDS’S 70TH BIRTHDAY PRESENT { P1 } S1 { Q1 } .......... { Pn } Sn { Qn } { P1 à ... à Pn } S1 || ... || Sn { Q1 à ... à Qn } where no variable free in Pi or Qi is changed in Sj (if i ≠ j) Verification of Concurrent Systems 19/06/2014 54

  28. EXAMPLE {x = 0}x := x + 1; x := x + 1{x = 2} {y = 0} y := y + 1; y := y + 1 {y = 2} {x = 0 à y = 0}x := x + 1; x := x + 1 || y := y + 1; y := y + 1 {x = 2 à y = 2} No interference between the threads Verification of Concurrent Systems 19/06/2014 55

  29. WHY IS THIS NOT SUFFICIENT? § Simultaneous reads not allowed 1. Distinguish between read and write accesses § Number of parallel threads is fixed Verification of Concurrent Systems 19/06/2014 56

  30. PERMISSIONS § Permission to access a variable § Value between 0 and 1 § Full permission 1 allows to change the variable § Fractional permission in (0, 1) allows to inspect a variable § Points-to predicate decorated with a permission § Global invariant: for each variable, the sum of all the permissions in the system is never more than 1 § Permissions can be split and combined Verification of Concurrent Systems 19/06/2014 57

  31. PERMISSION-BASED SEPARATION LOGIC Syntax extension of predicate logic: π φ ::= e.f → v | φ à φ | φ ‒ à φ | ... Meaning: π § e.f → v – e.f contains value v and thread has access right π on e.f § φ 1 à φ 2 – heap can be split in disjoint parts, satisfying φ 1 and φ 2, respectively § φ 1 ‒ à φ 2 – if heap extended with part that satisfies φ 1, composition satisfies φ 2 Notation: π e.f → v PointsTo( e.f , π , v ) π ∃ v. e.f → v Perm( e.f , π ) Verification of Concurrent Systems 19/06/2014 58

  32. Permissions on n equally distributed over threads EXAMPLE {PointsTo(x,1,0) à Perm(n, ½ ) } {PointsTo(y,1,0) à Perm(n, ½ )} x := x + n; x := x + n y := y + n; y := y + n {PointsTo(x,1,2*n) à Perm(n, ½ ) } {PointsTo(y,1,2*n) à Perm(n, ½ ) } {PointsTo(x,1,0) à PointsTo(y,1,0) à Perm(n,1) } x := x + n; x := x + n || y := y + n; y := y + n {PointsTo(x,1,2*n) à PointsTo(y,1,2*n) à Perm(n,1) }} Shared variable is only read Perm(x,1) = Perm(x, ½ ) à Perm(x, ½ ) No interference between the threads Verification of Concurrent Systems 19/06/2014 59

  33. WHY IS THIS NOT SUFFICIENT? § Simultaneous reads not allowed 1. Distinguish between read and write accesses § Number of parallel threads is fixed 2. Dynamic thread creation Thread specifications indicate how permissions should be distributed Verification of Concurrent Systems 19/06/2014 60

  34. class List { int val; List next; ... EXAMPLE } class T { List y; t1 t2 void run() { ... } } x := new List; x.val := ...; t2 := new T; run(){ t2.y := x; ... 1/2 1 fork t2; t1.x.val read y.val val read x.val; 1/2 ... ... } t2.y.val next join t2; x.val := ...; Verification of Concurrent Systems 19/06/2014 61

  35. SPECIFICATION FOR RUN METHOD IN T2 1/2 requires y. val → _ ; 1/2 ensures y .val → _ ; void run() {....} § Forking thread has to give up required permissions § Joining thread gains back ensured permissions What happens if run is specified as follows: 1 requires y .val → _ ; 1 ensures y .val → _ ; void run() {....} Verification of Concurrent Systems 19/06/2014 62

  36. class List { int val; List next; EXAMPLE ... } class T { t1 t2 List y; void run() { ... } x := new List; } x.val := ...; t2 := new T; run(){ t2.y := x; ... 0 1 fork t2(); t1.x.val read y.val val read x.val; ... 1 NOT ... } ALLOWED! t2.y.val next Now the join t2; permissions read x.val; are back x.val := ...; Verification of Concurrent Systems 19/06/2014 63

  37. THREAD TERMINATION t 1 1/2 1 1/2 t1 join t t2 join t Verification of Concurrent Systems 19/06/2014 64

  38. JOIN TOKEN § Extension of property language Join( e , π ) § Permission to pick up fraction π after thread e has terminated § Thread that creates thread t obtains Join-permission Join( t, 1) § Join-permission treated as any other permission: can be transferred and split Join( e, π ) à ⎯ à Join( e, π /2) à Join( e, π /2) Verification of Concurrent Systems 19/06/2014 65

  39. RULES FOR FORK AND JOIN § Precondition fork = precondition run § Which permissions are transferred from creating to the newly created thread § Postcondition run = postcondition join § Which permissions are released by the terminating thread, and can be reclaimed by another thread § Join only terminates when run has terminated § Specification for run final, it can only be changed by extending definition of predicates preFork and postJoin Verification of Concurrent Systems 19/06/2014 66

  40. FORK, JOIN AND THREAD {t.preFork} fork t {join(t, 1)} class Thread { pred preFork = true; {join(t, π )} join t {t.postJoin( π )} group postJoin<perm p> = true; requires preFork; ensures postJoin<1>; void run() { return null } } Verification of Concurrent Systems 19/06/2014 67

  41. EXAMPLE: CLASS FIB class Fib { int number; void init(n) { this.number := n; } void run() { .. } } Leonardo di Pisa/ Fibonacci Verification of Concurrent Systems 19/06/2014 68

  42. FIB’S RUN METHOD 1 pred preFork = number → _; p group postJoin<perm p> = number → _; requires preFork; ensures postJoin<1>; void run() { if (! (this.number < 2)) { f1 = new Fib; f1.init(number -1); f2 = new Fib; f2.init(number - 2); fork f1; fork f2; join f1; join f2; this.number := f1.number + f2.number } else this.number := 1; } Verification of Concurrent Systems 19/06/2014 69

  43. 1 pred preFork = number → _; p PROOF OUTLINE group postJoin<perm p> = number → _; requires preFork; void run() { if (! (this.number < 2)) { f1 = new Fib; f1.init(number -1); f2 = new Fib; f2.init(number - 2); {Perm(f1.number, 1) à Perm(f2.number, 1) à Perm(number, 1)} [fold preFork (2x)] {f1.preFork à f2.preFork à Perm(number, 1)} fork f1; {join(f1, 1) à f2.preFork à Perm(number, 1)} fork f2; {join(f1, 1) à join(f2, 1) à Perm(number, 1)} join f1; join f2; {f1.postJoin à f2.postJoin à Perm(number, 1)} [unfold postJoin (2x)] {Perm(f1.number, 1) à Perm(f2.number, 1) à Perm(number, 1)} this.number := f1.number + f2.number [close postJoin] {this.PostJoin}} else this.number := 1; } ensures postJoin(1); Verification of Concurrent Systems 19/06/2014 70

  44. MULTIPLE JOINS: PLOTTER Sampled Filter A data Filtered data Print on Raw input Sampler Plotter screen data Filter B Filter A and Filter B both join Sampler Plotter joins Filter A and Filter B Verification of Concurrent Systems 19/06/2014 71

  45. MAIN METHOD OF PLOTTER APPLICATION requires … ensures … void main(MVList lst) { {S*A*B*P} [abbreviates preFork – joinToken for Sampler, Filter A/B, Plotter] Sampler<len> smp = new Sampler; smp.init(data); smp.fork(); { Join(smp,1) * A * B * P } AFilter<len> af = new AFilter; af.init(data, smp); af.fork(); { Join(smp,1/2) * Join(af,1) * B * P } BFilter<len> bf = new BFilter; bf.init(data, smp); bf.fork(); { Join(af,1) * Join(bf,1) * P } Plotter<len> plt = new Plotter; plt.init(data,af,bf); plt.fork(); { Join(plt,1) } plt.join(); { plt.postJoin<1> } } } Verification of Concurrent Systems 19/06/2014 72

  46. REASONING ABOUT LOCKS Clément Hurlin Verification of Concurrent Systems 19/06/2014 73

  47. RESOURCE INVARIANT – CLASSICAL APPROACH § Lock x acquired and released with lock x and unlock x § Each lock has associated resource invariant § Lock acquired resource invariant lend to thread § Lock released resource invariant taken back from thread § Class Object contains predicate {true} pred inv = true; lock x ; { I } § In rules: if I is resource invariant of x lock x ; {true} lock x { I } { I à I } { I }unlock x {true} ... § This is sound only for single-entrant locks Resource I has been duplicated! Verification of Concurrent Systems 19/06/2014 74

  48. EXTRA PREDICATES § Add extra predicates to logic π § φ ::= e.f → v | φ à φ | φ ‒ à φ | Lockset( S ) | S contains e § Lockset ( S ) - S is the multiset of locks held by current thread § S contains E - multiset S contains e Multiset: set where you count the number of occurrences of each element For multiset S : x.x.S ≠ x .S Verification of Concurrent Systems 19/06/2014 75

  49. RULES FOR LOCKING Will be {Lockset( S ) à ¬ ( S contains u ) à u .initialized} explained lock u {Lockset( u.S ) à u .inv} {Lockset( u.S ) }lock u {Lockset( u.u.S )} Verification of Concurrent Systems 19/06/2014 76

  50. RULES FOR UNLOCKING {Lockset( u.S ) à u .inv}unlock u {Lockset( S )} {Lockset( u.u.S ) }unlock u {Lockset( u.S )} Verification of Concurrent Systems 19/06/2014 77

  51. e.unlocked(e ′ ) = Lockset( e ′ ) à ¬ (e ′ contains e) EXAMPLE class Account { int balance; 1 pred inv = this.balance → _ ; requires initialized à unlocked( S ); ensures Lockset( S ); void deposit(int x) { {initialized à unlocked( S )} lock this; {Lockset( S · this) à inv} open and close of this.balance := this.balance + x; predicate {Lockset( S · this) à inv} unlock this; {Lockset( S )} } Verification of Concurrent Systems 19/06/2014 78

  52. NEW THREADS HAVE EMPTY LOCKSET Specification for method run becomes: requires preFork à Lockset(nil); ensures postJoin<1>; Empty multiset method run() { return null; } Verification of Concurrent Systems 19/06/2014 79

  53. SPECIFICATIONS FOR WAIT AND NOTIFY requires Lockset( S ) à S contains this à inv; ensures Lockset( S ) à inv; void wait(); requires Lockset( S ) à S contains this; ensures Lockset( S ); void notify(); Verification of Concurrent Systems 19/06/2014 80

  54. LOCK INITIALISATION § Locks created dynamically § Initialisation of resource invariant necessary § Object can only be used as lock when its resource invariant has been initialised § Special annotation command commit to mark that resource invariant is initialised § Default position for commit: end of constructor Verification of Concurrent Systems 19/06/2014 81

  55. LOCK INITIALISATION EXAMPLE § Class ThreadPool contains Vector v to store threads § Construction of ThreadPool gives Perm(v, 1) § Resource invariant inv = Perm(v, 1) § Constructor body: § Initialise v to empty Vector § commit: Perm(v, 1) stored inside lock § Now lock on ThreadPool can be acquired and released by threads, to add and remove threads to threadpool § Only when thread has lock on ThreadPool, does it have permission to access v Verification of Concurrent Systems 19/06/2014 82

  56. EXTRA PREDICATES § Add extra predicates to logic π § φ ::= e.f → v | φ à φ | φ ‒ à φ | Lockset( S ) | S contains e | e. fresh | e. initialized § Lockset ( S ) - S is the multiset of locks held by current thread § S contains e - multiset S contains e § e. fresh - e’ s resource invariant not yet initialized § e. initialized - e’ s resource invariant initialized Some of these atomic propositions can be freely duplicated, some cannot Verification of Concurrent Systems 19/06/2014 83

  57. COPYABLE VERSUS NON-COPYABLE § Copyable properties: persistent state properties Once established, they hold forever § Non-copyable properties: transient state properties Properties that hold temporarily § Axiom for copyable properties (to use in proofs): (G ∧ F) ‒ à (G à F) § This implies F ‒ à (F à F) i.e., formula can be duplicated freely Verification of Concurrent Systems 19/06/2014 84

  58. COPYABLE VERSUS NON-COPYABLE § Lockset ( S ) - non-copyable § S contains e - copyable § e. fresh - non-copyable § e. initialized - copyable Verification of Concurrent Systems 19/06/2014 85

  59. RULES FOR LOCK CREATION AND COMMIT Now we can formulate the rules for new and commit {true} v := new C { ∃ X.v → X à X.f1 → null à ... à X.fn → à v .fresh} {Lockset(S) à u .inv à u .fresh} commit u {Lockset( S ) à ¬ ( S contains u ) à u .initialized} Verification of Concurrent Systems 19/06/2014 86

  60. FUNCTIONAL VERIFICATION OF CONCURRENT PROGRAMS WORK IN PROGRESS Marina Zaharieva – Stojanovski Verification of Concurrent Systems 19/06/2014 87

  61. EXAMPLE: PARALLEL INCREASE How to prove: Ghost code solution: {x = a + b & a == 0 & b == 0} {x == 0} {x == a + b & a == 0} || {x == a + b & b == 0} <x := x + 1;> || <x := x + 1;> <x := x + 1;> || <x := x + 1;> <a := 1;> // ghost || <b :=1;> //ghost {x == 2} {x == a + b & a == 1} || {x == a + b & b == 1} {x == a + b & a == 1 & b == 1} {x == 2} Problem: {x == 0} Our approach: < x := x + 1;> Maintain abstract history of updates {x == 1} unstable: assertions can be made invalid by other threads Verification of Concurrent Systems 19/06/2014 88

  62. Client: c = new Counter(0); AS A JAVA-LIKE PROGRAM fork t1; //t1 calls c.increase(); fork t2; //t2 calls c.increase(); join t1; join t2; class Counter{ int data; // Is c.data == 2 ? Lock l; resource_inv = exists v. PointsTo(data, 1, v); Permission to read and update requires true; data ensures true; void increase(){ Needed: l.lock(); // obtain PointsTo(data, 1, v); A specification of data ++; increase that l.unlock(); // loose PointsTo(data, 1, v + 1); records the update // now we don’t know anything about data anymore } } Verification of Concurrent Systems 19/06/2014 89

  63. SEPARATE PERMISSION AND VALUE [Separation Rule] PointsTo(x, 1, v) *-* Perm(x, 1) * Init(x, {v}) * Hist(x, 1, {}); § Perm(x,1) - permission to access x § Init(x, {v}) - initial value of x § Hist(x, 1, H) - history of all updates/actions to x Verification of Concurrent Systems 19/06/2014 90

  64. A HISTORY OF ACTIONS History H is process algebra term composed of user-defined actions (use ACP) Examples action a <int x>(int k) = \old(x) + k; action b <list l>(int e) = cons(\old(l), e); action c <int k>(int w) = w; Verification of Concurrent Systems 19/06/2014 91

  65. COUNTER SPECIFICATION class Counter { int data; Lock l; //resource_inv = Perm(data, 1); //action a <int x> () = \old(x) + 1; Record LOCAL changes in the history requires Hist(data, p, H); ensures Hist(data, p, H.a); void increase(){ l.lock(); /* start a */ data ++; /* record a */ l.unlock(); } } Verification of Concurrent Systems 19/06/2014 92

  66. HISTORY MANIPULATION [SplitHist Rule] Hist(x, p, H) *-* Hist(x, p/2, H 1 ) * Hist(x, p/2, H 2 ); H = H 1 || H 2 § Forking a thread: mark with special synchronisation action (s, s) H = H.s || s § Current thread: H.s § New thread: s § Joining a thread: continue with the parallel composition of the local histories Verification of Concurrent Systems 19/06/2014 93

  67. CLIENT-SIDE REASONING To reason about the value in data , we need: § Init(data, V) predicate § Full Hist(data, 1, H) token After the client of the Counter joins both threads, we can reinitialize the History: Init(data, {0}) * Hist(data, 1, s t1 . s t2 || s t1 . a() || s t2 . a()) *-* Init(data, {2}) * Hist(data, 1, {}) The only possible value for data is 2 Verification of Concurrent Systems 19/06/2014 94

  68. NON-DETERMINISTIC BEHAVIOUR class Counter{ //action a <int x> (int n) = \old(x) + n; //action b <int x> (int n) = \old(x) * n; requires Hist(data, p, H); ensures Hist(data, p, H.a(n)); Client: void increase(int n){ l.lock(); data = data + n; l.unlock(); c = new Counter(0); } fork t1; //t1: c.increase(4); requires Hist(data, p, H); fork t2; //t2: c.multiply(4); ensures Hist(data, p, H.b(m)); join t1; void increase(int m){ join t2; l.lock(); data = data * m; l.unlock(); } // What is c.data? } Verification of Concurrent Systems 19/06/2014 95

  69. COMPUTING POSSIBLE VALUES Reinitialisation of the History: Init(data, {0}) * Hist(data, 1, s t1 . s t2 || s t1 . a(4) || s t2 . b(4)) *-* Init(data, {0}) * Hist(data, 1, a(4).b(4) + b(4).a(4)) *-* Init(data, {4,16}) * Hist(data, 1, {}) Extensions § Histories for multiple variables § Data structures Verification of Concurrent Systems 19/06/2014 96

  70. CLASS INVARIANTS IN CONCURRENT SETTING § Class invariant: property about reachable object state § Typical: relation between object’s fields § In sequential setting: breaking allowed within method boundaries § In concurrent setting: breaking allowed when violation cannot be observed § Explicit pack and unpack operations {holds(v.I, 1)} unpack(v.I){unpacked(v.I, 1) ∗ v.I} {v ̸ = null ∗ PointsTo(v.f,1,w) ∗ \forall ∗ (I ∈ inv(V),v.f ∈ fp(v.I). unpacked(v.I, π ))} v.f = w; {PointsTo(v.f,1,w) ∗ \forall ∗ (I ∈ inv(V),v.f ∈ fp(v.I). unpacked(v.I, π ))} Usage: {unpacked(v.I, 1) ∗ v.I} pack(v.I) {holds(v.I, 1)} {holds(v.I, π ) ∗ v.I} c {F } {holds(v.I, π )} c {F } Verification of Concurrent Systems 19/06/2014 97

  71. REASONING ABOUT GPU PROGRAMS Verification of Concurrent Systems 19/06/2014 98

  72. GPU KERNELS § Originally for graphics § More and more used also for other applications § Single-Instruction-Multiple-Thread model (similar to Vector machines) § Host (typically CPU) invokes kernel on separate device § Kernel: § Many threads § Execute all same code § But on different data § OpenCL: extended subset of C, platform-independent Verification of Concurrent Systems 19/06/2014 99

  73. VECTOR ADDITION AS OPENCL KERNEL __global _kernel void square( _global float* input, Where are the arrays stored _global float* output) { int i = get_global_id(0); output[i] = input[i] * input[i]; } Verification of Concurrent Systems 19/06/2014 100

Recommend


More recommend