Download presentation
Presentation is loading. Please wait.
1
Concurrency Verification
2
Why concurrency verification
Concurrent programs show in many systems Multi-task support in OS kernels Handling interrupts from external devices … Will be more common Multi-core processors Intellectually interesting Correctness/incorrectness are not obvious
3
Shared-State Concurrency Model
B Memory
4
Execution Model: Simple Examples
[ 100 ] := 3 [ 100 ] := 5 [ 100 ] := 3 [ 101 ] := 5 100 101 3 5 100 3/5 Don’t know which one is written first, but order doesn’t matter. Order may affect the result if threads share resources.
5
Execution Model: Simple Examples
It is difficult to discuss resource sharing with memory pointer aliasing. T1: T2: [ x ] := 3 [ y ] := 5 x x y y 3/5 3 5
6
Execution Model: Simple Examples
C1n C21; C22; C2n T1 T2 Non-deterministic interleaving may produce exponential number of execution traces; Different traces may lead to different results (depends on the resource sharing).
7
Challenges to reason about concurrent programs
Sharing of resources makes the result dependent on the ordering of execution Non-deterministic interleaving produces exponential num. of possible ordering Memory pointer aliasing makes it difficult to tell how resources are shared
8
Outline of this Lecture
Separation Logic Review Concurrent Separation Logic (CSL) Rely-Guarantee Reasoning (R-G) Modular verification of fine-grained concurrency – recent progress
9
Separation Logic A Hoare-style program logic: { p } C { q }
[Ishtiaq&O’Hearn’01,Reynolds’02] A Hoare-style program logic: { p } C { q } What’s new here is the assertion language.
10
Separation Logic Assertions
emp empty heap l n n l p q p q p q
11
Separation Logic Assertions
emp empty heap l n n l p q p q l_ defined as n. l n ln defined as (ln) true n l
12
Properties pemp p pq qp pp p ptrue p pp p
(l_)(l_) false p ptrue ptrue p
13
Assertions Model Ownership
[l] := m; {(l m)} {emp} [l] := m; {???} Ownership cannot be duplicated: (l_) (l_)(l_)
14
Strength of Separation
{(xn) (yn)} [x] := m; {(xm) (yn)} {(xn) (yn)} [x] := m; {(xm) (yn)} what if x=y ?
15
A Frame Rule for Modularity
C p q r { p } C { q } { p r } C { q r } r Another example showing the strength of separation!
16
Specification of a List
top … List (top) (top = null) emp next. top (_, next) List ( next ).
17
Example: getNode getNode() if (top <> null){ { List (top) }
r1 = top; r2 = top.next; top = r2; } else {r1 = null } { List (top) } { List (top) top null } { next. top (_, next) List ( next ) } { r1 = top next. top (_, next) List ( next ) r2 = next } { r1 (_, _) List ( r2 ) } { r1 (_, _) List ( top ) } { List ( top ) * (top = r1 = null emp r1 (_, _) ) }
18
Reading Materials See the miniCourse webpage of John Reynolds:
19
Outline of This Lecture
Separation Logic Review Concurrent Separation Logic (CSL) Rely-Guarantee Reasoning (R-G) Modular verification of fine-grained concurrency – recent progress
20
Separation Logic for Concurrency
[ 100 ] := 3 [ 100 ] := 5 [ 100 ] := 3 [ 101 ] := 5 100 101 3 5 100 3/5 Separation is an effective way to control interference.
21
The language x := e | [e] := e' | x := [e] | cons(e)
| dispose(e) | C; C | C || C | … A new construct: l.acq() | l.rel()
22
Operational Semantics
Program state: (s, h, L) where L locks {0, 1} L(l) = 1 (l.acq(), (s, h, L)) (skip, (s, h, L{l 0}) ) (l.rel(), (s, h, L)) (skip, (s, h, L{l 1}) )
23
How to control interference?
Basic idea: Each thread has private memory (resource) The private resource can be arbitrarily used Private resources of different threads are disjoint Shared resources are protected by locks Shared resources are disjoint with local resources Can only be used when the lock is acquired (i.e. in critical regions) Different locks protect different resources
24
Basic Memory Model Shared (accessible only in critical regions)
Private Private
25
Basic Memory Model
26
Basic Memory Model
27
Basic Memory Model
28
Basic Memory Model When the resource is acquired/released, it must be well-formed. The well-formedness is resource invariant.
29
Concurrent Separation Logic (CSL)
Lock-based critical regions (CR): l.acq(); … l.rel() Invariants about memory protected by locks: = {l1 r1, …, ln rn} r1, …, rn disjoint l1 ln r1 rn
30
Concurrent Separation Logic
(l1) p2 l1.rel() p1 (l2) (l1) p2 p1 (l2) p2 (l1) l1.acq() …
31
CSL – Formalization Key ideas:
Threads can only access disjoint resources at the same time. p q p q Transfer is logical: no memory copying ┝ {p1} C1 {q1} ┝ {p2} C2 {q2} ┝ {p1 p2} C1 || C2 {q1 q2}
32
CSL – Parallel Composition
ln p q p q r1 rn ┝ {p1} C1 {q1} ┝ {p2} C2 {q2} ┝ {p1 p2} C1 || C2 {q1 q2} Transfer is logical: no memory copying I() p1 p2 I() q1 q2 We’ll define I() later.
33
CSL - Locks Lock acquire: Lock release: ┝ {p} l.acq() {p (l)}
Note: do not support reentrant locks Lock release: ┝ {p (l)} l.rel() {p} Compare the rules with cons and dispose
34
Examples: List = { l List(x) } getNode(): l.acq(); -{emp} …
l.rel(); -{emp} x … y -{emp * List(x)}; -{Node(y) * List(x)} -{Node(y)}
35
Examples (l) = full c _, _ full emp Put (x): l.acq();
while( full ){ l.rel(); } c := x; full := true; Get (y): l.acq(); while( !full ){ l.rel(); } y := c; full := false; (l) = full c _, _ full emp
36
Examples (l) = full c _, _ full emp Put (x): l.acq();
while( full ){ l.rel(); } (l) = full c _, _ full emp {x _, _ } {x _, _ (l) full } {x _, _ } c := x; full := true; l.rel(); {x _, _ (l) } {c _, _ } {x _, _ } {full c _, _ } {x _, _ (l) } {(l) } {emp } {x _, _ (l) full }
37
Examples (l) = full c _, _ full emp get (y): l.acq();
while( !full ){ l.rel(); } (l) = full c _, _ full emp {emp} { (l) full } {c _, _ } y := c; full := false; l.rel(); { (l) } {y _, _ } { emp } {y _, _ (full emp) } {(l) } {y _, _ (l)} {y _, _ } {(l) full }
38
Examples {x _, _ } put (x) {emp } {emp} get (y) {y _, _ } {emp}
x := cons(a, b); put(x); get(y); use(y); dispose(y); {x _, _ } {y _, _ } {y _, _ } {emp } {emp} {emp emp}
39
Outline of This Lecture
Separation Logic Review Concurrent Separation Logic (CSL) Rely-Guarantee Reasoning (R-G) Modular verification of fine-grained concurrency – recent progress
40
Owicki-Gries Method Susan Owicki and David Gries, 1975
Other rules are the same as Hoare logic rules
41
Non-Interference Key idea: execution of a statement does not invalidate proofs of other code fragments that may run in parallel with the statement in question. Given a proof {p} c {q}, and a command T whose precondition is pre(T), we say T does not interfere with {p} c {q} if - {q pre(T)} T {q}; and - for all c’ in c (but not in await), {pre(c’) pre(T)} T {pre(c’)}
42
Non-Interference {p1} c1 {q1}, … {pn} cn {qn} are interference-free if, for any await or primitive statement T (not inside await) in ci, and for all j i, T does not interfere with {pj} cj {qj}. This method is not compositional!
48
Rely-Guarantee Reasoning
Use rely (R) and guarantee (G) conditions to summarize the behaviors of environments and the thread itself. G G G p q R R R
49
Rely-Guarantee Reasoning
R and G: specification of state transitions example: x’ x G G G p q R R R
50
Assume-Guarantee Reasoning
Thread T and its environment Environment: the collection of all other threads except T R: assumption about environment’s transition G: guarantee to the environment p, q: pre-/post-conditions
51
R-G reasoning p1p2 G1 G2 p1 p2 R1 R2 p1p2 p1p2 p2 p1
52
Inference Rules
53
Inference Rules (2)
54
Example {x = 0} < x := x+1 > || < x := x+1 > {x = 2}
55
{x = 0} y := 0; z := 0; {x = y+z y = 0 z = 0} {x = y+z y = 0}
G1 y = 0 y’ = 1 x’ = x+1 z’ = z G2 z = 0 z’ = 1 x’ = x+1 y’ = y R1 G2 R2 G1 {x = 0} y := 0; z := 0; {x = y+z y = 0 z = 0} {x = y+z y = 0} {x = y+z z = 0} < x := x+1; y := 1; > < x := x+1; z := 1; > || {x = y+z y = 1} {x = y+z z = 1} {x = y+z y = 1 z = 1} {x = 2}
56
Soundness Partial correctness Safety Preservation of R/G
57
Outline of This Lecture
Separation Logic Review Concurrent Separation Logic (CSL) Rely-Guarantee Reasoning (R-G) Modular verification of fine-grained concurrency – recent progress
58
An Optimistic Non-blocking Stack
Top n Next n Next … pop( ){ local done, next, t; done = false; while (!done) { t = Top; if (t==null) return null; next = t.Next; done = CAS(&Top, t, next); } return t; ABA problem leads to corrupted stacks 58
59
ABA Problem Threads T1 and T2 are interleaved as follows: T2:
a = pop(); b = pop(); push(a); T1: pop() { t = Top next = t.Next interrupted resumes CAS(&Top,t,next) succeeds stack corrupted Top t A Top next B Top C Timeline 59
60
Fix Bugs with Hazard Pointers [Michael04]
pop( ){ local done, next, t, t1; done = false; while (!done) { t = Top; if (t==null) return null; HP[tid] = t; t1 := Top; if (t == t1){ next = t.Next; done = CAS(&Top, t, next); } retireNode(t); HP[tid] = null; return t; push(x) local done, t; done = false; while(!done) { t = Top; x.Next := t; done = CAS(&Top, t, x); } return true; How to verify its correctness? 60
61
The key of concurrency verification is to control sharing of resources.
Two classic methods: Concurrent Separation Logic (CSL) [O’Hearn 2004] Rely-Guarantee Reasoning [Jones'83]
62
Concurrent Separation Logic
Very good modularity Reduce concurrency verification to seq. verification Frame rules (will explain later) Invariant not very expressive for fine-grained alg. How to say “x cannot decrease in C”? (necessary for fine-grained algorithms) need extensive use of auxiliary variables see [Parkinson et al.’07] atomic{ -{ I } C -{ I } }
63
The key of Concurrency Verification is to control sharing of resources.
Two classic methods: Concurrent Separation Logic (CSL) [O’Hearn 2004] Rely-Guarantee Reasoning [Jones'83]
64
Rely-Guarantee Reasoning
(R1, G1) (R2, G2) All resources are shared, but access must follow contracts (R-G)!
65
Rely-Guarantee Reasoning
Thread T and its environment Environment: the collection of all other threads except T R: rely condition about environment’s transition G: guarantee to the environment p, q: pre-/post-conditions (R,G) ┝ {p} C {q}
66
Rely-Guarantee Reasoning
(R1, G1) (R2, G2) Non-Interference (NI): G2 R1 and G1 R2
67
Example Modularity broken! 100 101 … [100] := m; … [101] := n;
G1: [101] = [101]' R1: [100] = [100]' G2: [100] = [100]' R2: [101] = [101]'
68
Rely-Guarantee Reasoning
Expressive for fine-grained concurrency “x cannot decrease”: x' x Treat everything as shared; no private data Limited support of modularity
69
Expressiveness and Modularity
Expressiveness of interference R-G Modularity (local reasoning) CSL How to reach here?
70
Modular verification of fine-grained concurrency
SAGL [Feng et al’07] RGSep [Vafeiadis & Parkinson’07] LRG [Feng’09] HLRG [Fu et al'10] Deny-Guarantee [Dodds et al'09]
71
SAGL: Separated A-G Logic [Feng et al'07]
Key idea: Separate resources into local and shared! (R1, G1) (R2, G2) (R2, G2) Private Shared Private
72
SAGL [Feng et al’07] Separate resources into shared and private
(R,G) ┝ {(a, p)} C {(r, q)} Separate resources into shared and private Shared can be accessed at any time governed by R and G more expressive than I in CSL Exclusive access to private resources follows local reasoning in CSL not specified in R and G better memory modularity
73
SAGL – Access Private Resource
a1a2 p2 p1 a1a2 p2'
74
Example: regained data modularity
100 101 -{(emp , 100 _) } -{(emp , 101 _)} … [100] := m; … [101] := n; G1: emp R1: emp G2: emp R2: emp
75
SAGL – Access Shared Resource
p1 a1a2 p2 G2 p1 a1a2' p2 a1 R1 a1 R-G reasoning: a special case where p1 and p2 are emp.
76
SAGL - Redistribution p1 a1a2' p2 p1 a1a2 p2 p1 a1a2 p2 G2 R1
77
Expressiveness and Modularity
Expressiveness of interference R-G More modular: do not specify local data in R/G Modularity (local reasoning) SAGL (RGSep) More expressive for interference: R/G vs. invariants I CSL But still not as modular as CSL!
78
Limitations of R-G reasoning
79
An Example … head n1 n2 nxt n1 n2 nxt rn1 rn2 Producer: Consumer:
x := newNode (rn1, rn2, null); push(head, x);
80
An Example … head n1 n2 nxt n1 n2 nxt rn1 rn2 Producer: Consumer:
nd := pop(head); x := newNode (rn1, rn2, null); T1(nd) || T2(nd) push(head, x);
81
Cannot be verified using R-G
head n1 n2 nxt n1 n2 nxt … rn1 rn2 Producer: Consumer: Problem #1: Specify and verify T1 || T2 without knowing the context (the stack) nd := pop(head); x := newNode (rn1, rn2, null); T1(nd) || T2(nd) push(head, x);
82
Cannot be verified using R-G
head n1 n2 nxt n1 n2 nxt … rn1 rn2 Producer/Consumer only share the stack Producer: Consumer: Problem #2: How to hide locally shared resource nd from Producer nd := pop(head); x := newNode (rn1, rn2, null); nd is locally owned by consumer T1(nd) || T2(nd) push(head, x);
83
Cannot be verified using R-G
head n1 n2 nxt n1 n2 nxt … rn1 rn2 Producer: Consumer: nd := pop(head); x := newNode (rn1, rn2, null); Problem #3: Rely/guarantee conditions cannot specify sharing of dynamic resources. T1(nd) || T2(nd)
84
Extensions in Local Rely-Guarantee Reasoning
85
Local Rely-Guarantee Reasoning (LRG)
Actions (a, R, G): S p S' q p q S p S p [p] Here p and q are normal separation logic assertions (state predicates) a a a' S1 S2 S1' S2' a'
86
Limitations of R-G … head n1 n2 nxt n1 n2 nxt Problem #1:
rn1 rn2 Producer: Consumer: Problem #1: Specify and verify T1 || T2 without knowing the context (the stack) nd := pop(head); x := newNode (rn1, rn2, null); T1(nd) || T2(nd) push(head, x);
87
Local Specification & Frame Rule
R0 G0 are rely/grt, p is precondition, p’ is post condition Rely/guarantee spec. precondition postcondition (R0,G0)┝ {p} C {p'} side conditions omitted (frame) (R0R1,G0G1)┝ {pr} C {p'r}
88
Local Specification & Frame Rule
<R0, G0> S0' p' r R0, G0, p and p' specify resources used locally in C: (R0R1,G0G1)┝ {pr} C {p'r } S1 <R1, G1> S1' Stable(r, R1) [r] G1 r S1 and S1' may be different R0 G0 are rely/grt, p is precondition, p’ is post condition if S |= r and (S, S') |= R1, then S' |= r identity transitions preserving r would satisfy G1 (R0,G0)┝ {p} C {p'} Stable(r, R1) side conditions omitted [r] G1 (frame) (R0R1,G0G1)┝ {pr} C {p'r}
89
Limitations of R-G … head n1 n2 nxt n1 n2 nxt Problem #2:
rn1 rn2 Producer/Consumer only share the stack Producer: Consumer: Problem #2: How to hide locally shared resource nd from Producer nd := pop(head); x := newNode (rn1, rn2, null); nd is locally owned by consumer T1(nd) || T2(nd) push(head, x);
90
Limitations of R-G … head n1 n2 nxt n1 n2 nxt Problem #3:
rn1 rn2 Producer: Consumer: nd := pop(head); x := newNode (rn1, rn2, null); Problem #3: Rely/guarantee conditions cannot specify sharing of dynamic resources. T1(nd) || T2(nd)
91
Distinguish Local and Shared Resources [Feng et al
Distinguish Local and Shared Resources [Feng et al. 07, Vafeiadis&Parkinson 07] p r S0 S1 (R1,G1)┝ {pr} C {p'r' } <R1, G1> S0' S1' p' r' R/G can be viewed as a “window” revealing (shared) part of the state to the outside world.
92
The Hide Rule R/G are interfaces between threads.
93
The Hide Rule R/G are interfaces between threads. p SL S0 S1 S0
(R0R1,G0G1)┝ {p} C {q} <R0, G0> <R1, G1> SL' S0' S1' S0' q (R0R1,G0G1)┝ {p} C {q} side conditions omitted (R1,G1)┝ {p} C {q} (hide)
94
Verification of the Consumer
Rstk/Gstk: specify the stack - { pstk } (Rstk,Gstk)┝ {pstk} C1 {qstk pnd} nd := pop(head); C1 (Rnd,Gnd)┝ {pnd} C2 {qnd} (Rnd,Gnd)┝ {pnd} C2 {qnd} - { qstk pnd} T1(nd) || T2(nd) C2 Rnd/Gnd: specify the node nd
95
Verification of the Consumer
Rstk/Gstk: specify the stack - { pstk } (Rstk,Gstk)┝ {pstk} C1 {qstk pnd} (Rstk,Gstk)┝ {pstk} C1 {qstk pnd} nd := pop(head); (Rnd,Gnd)┝ {pnd} C2 {qnd} - { qstk pnd} T1(nd) || T2(nd) Rnd/Gnd: specify the node nd … (Rnd,Gnd)┝ {pnd} C2 {qnd} (frame) (RndRstk,GndGstk)┝ {qstkpnd} C2 {qstkqnd} (hide) (Rstk,Gstk)┝ {qstkpnd} C2 {qstkqnd}
96
Verification of the Consumer
Rstk/Gstk: specify the stack - { pstk } (Rstk,Gstk)┝ {pstk} C1 {qstk pnd} nd := pop(head); (Rnd,Gnd)┝ {pnd} C2 {qnd} - { qstk pnd} Local spec. and reasoning T1(nd) || T2(nd) Rnd/Gnd: specify the node nd - { qstk qnd} … (Rnd,Gnd)┝ {pnd} C2 {qnd} (frame) (RndRstk,GndGstk)┝ {qstkpnd} C2 {qstkqnd} (hide) Hide the local sharing of nd (Rstk,Gstk)┝ {pstk} C1 {qstk pnd} (Rstk,Gstk)┝ {qstkpnd} C2 {qstkqnd} (seq) (Rstk,Gstk)┝ {pstk} C1 ; C2 {qstk qnd}
97
A Missing Part Separating conjunction of SL assertions:
p1 p2 Separating conjunction of actions: How to prevent this? l1 l2 l3 l2 l1 l3 l3 l1 l2 a a1 a2 l1 l2 l3 We may have many “bad” a1 and a2!
98
Invariant as Fences Invariant I (a state assertion):
specifies basic well-formedness of resources. Invariant fenced actions: I ► a ( [I] a ) ( a (I I) ) precise(I) I is a normal state predicate S |= I (S, S) |= a Identity transition over well-formed resources satisfies a.
99
Invariant as Fences Invariant I : Invariant fenced actions:
specifies basic well-formedness of resources. Invariant fenced actions: I ► a ( [I] a ) ( a (I I) ) precise(I) (S, S') |= a (S |= I) (S' |= I) Action a preserves the basic well-formedness of resource.
100
Invariant as Fences Invariant I : Invariant fenced actions:
specifies basic well-formedness of resources. Invariant fenced actions: I ► a ( [I] a ) ( a (I I) ) precise(I) Given a state, there is at most one sub-state satisfying I
101
Cannot find an I such that I ► a1 or I ► a2.
Invariant as Fences How to prevent this? Cannot find an I such that I ► a1 or I ► a2. l1 l2 l3 l3 l1 l2 l2 l1 l3 a a1 a2 l1 l2 l3 We may have many “bad” a1 and a2!
102
Invariant as Fences Basic judgment: I,R,G┝ {p} C {q}
R/G are fenced by I I0I1,R0R1,G0G1┝ {p} C {q} I1,R1,G1┝ {p} C {q} (hide) I1 ► {R1,G1} II',RR',GG'┝ {pr} C {qr} Stable(r, R') (frame) I,R,G┝ {p} C {q} I' ► {R',G'} r I' see the paper for details!
103
Expressiveness and Modularity
Expressiveness of interference R-G Modularity (local reasoning) SAGL RGSep R * R' G * G' LRG CSL
104
HLRG – Adding Histories to R/G [Fu et al.’10]
LRG still not good enough to verify the stack algorithm Needs to say “if something happened before in history, then I guarantee that …” Existing approach: heavy use of history variables. Our solution: Adding past-tense temporal operators to assertions and R/G
105
HLRG - Assertion Language
State Assertions: Trace Assertions: P , Q ::= B | E E | P * Q | … p, q, R, G::= P | Id | p q | …
106
p q p q q q q p holds over the historical trace q holds ever since
Time p holds over the historical trace p s0 s1 s2 s3 s4 s5 s6 q Suppose this is program trace, from the initial state s0 to the current state s6, this trace satisfies p triangle q , it requires that p holds over the historical trace and q holds ever since. q q q q holds ever since 106
107
p = (p true) p Time s0 s1 s2 s3 s4 s5 s6 p We can use this open triangle to define some useful notations. For example this, Assertion ♦− p says that p was once true in the history, including the current trace. p was once true in the history, including the current trace. 107
108
… p = ( p) p p p p p holds at every step in the history Time s0 s1 s2
We can define box p from diamond p. Box p holds if and only if p holds at every step in the history p p holds at every step in the history 108
109
p q Time p q s6 s5 s4 s3 s2 s1 s0
110
HLRG R, G, I┝ {p} C {q} Now R, G, I, p and q are all trace assertions
The stack algorithm verified without using history variables!
111
Expressiveness and Modularity
Expressiveness of interference R-G Modularity (local reasoning) SAGL RGSep LRG HLRG use trace assertions CSL
112
Expressiveness and Modularity
Expressiveness of interference R-G Modularity (local reasoning) SAGL RGSep A separation algebra for interference (D-G) LRG HLRG Deny-Guarantee CSL
113
What do we learn? We need expressive assertions to specify fine-grained interference! Trace assertions p, p, Invariant I Actions (R,G) All resources as shared Separate local & shared in R/G Separation gives us local reasoning (modularity)! R R' and G G' (p) (q) …
114
Take-home messages: We need expressive assertions to specify fine-grained interference! Separation gives us local reasoning (modularity)!
115
A More Recent Survey By Ilya Sergey [Dagstuhl 15191]
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.