concurrency verification. why concurrency verification concurrent programs show in many systems...

Post on 02-Jan-2016

226 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Concurrency Verification

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

Shared-State Concurrency Model

Memory

A B

100100 101

Execution Model: Simple Examples

T1: T2:

[ 100 ] := 3 [ 101 ] := 5

3 5

T1: T2:

[ 100 ] := 3 [ 100 ] := 5

3/5

Don’t know which one is written first, but order doesn’t matter.

Order may affect the result if threads share resources.

Execution Model: Simple Examples

T1: T2:

[ x ] := 3 [ y ] := 5

x

y

x

y

3 53/5

It is difficult to discuss resource sharing with memory pointer aliasing.

Execution Model: Simple Examples

T1: T2:

C11;

C12;

C1n

C21;

C22;

C2n

T1

T1 T1

T2

T2 T2

Non-deterministic interleaving may produce exponential num. of execution traces;

Different traces may lead to different results (depends on the resource sharing).

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

Outline of this Lecture

• Separation Logic Review

• Concurrent Separation Logic (CSL)

• Rely-Guarantee Reasoning (R-G)

• Modular verification of fine-grained concurrency – recent progress

Separation Logic

A Hoare-style program logic:

{ p } C { q }

What’s new here is the assertion language.

[Ishtiaq&O’Hearn’01,Reynolds’02]

Separation Logic Assertions

l n nl

p q p q

emp empty heap

p qp q

Separation Logic Assertions

l n nl

p q p q

emp empty heap

l_ defined as n. l n

ln defined as (ln) truel

n

Properties

pemp p

pq qp

pp p ptrue p

pp p (l_)(l_) false

p ptrue

ptrue p

Assertions Model Ownership

{(l _)}

[l] := m;

{(l m)}

{emp}

[l] := m;

{???} Ownership cannot be duplicated: (l_) (l_)(l_)

Strength of Separation

{(xn) (yn)}

[x] := m;

{(xm) (yn)}

{(xn) (yn)}

[x] := m;

{(xm) (yn)}

what if x=y ?

A Frame Rule for Modularity

{ p } C { q }

{ p r } C { q r }

Another example showing the strength of separation!

C

p

q

r

r

Specification of a List

top…

List (top) (top = null) emp

next. top (_, next) List ( next ).

Example: getNode

getNode()

if (top <> null){

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 (_, _) ) }

Reading Materials

http://www.cs.cmu.edu/~jcr/

See the miniCourse webpage of John Reynolds:

Outline of This Lecture

• Separation Logic Review

• Concurrent Separation Logic (CSL)

• Rely-Guarantee Reasoning (R-G)

• Modular verification of fine-grained concurrency – recent progress

Separation Logic for Concurrency

100100 101

T1: T2:

[ 100 ] := 3 [ 101 ] := 5

3 5

T1: T2:

[ 100 ] := 3 [ 100 ] := 5

3/5

Separation is an effective way to control interference.

The language

x := e | [e] := e' | x := [e] | cons(e)

| dispose(e) | C; C | C || C | …

A new construct:

l.acq() | l.rel()

Operational Semantics

(l.acq(), (s, h, L)) (skip, (s, h, L{l 0}) )

Program state: (s, h, L)

where L locks {0, 1}

L(l) = 1

(l.rel(), (s, h, L)) (skip, (s, h, L{l 1}) )

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

Basic Memory Model

Private PrivateShared (accessible only in critical regions)

Basic Memory Model

Basic Memory Model

Basic Memory Model

Basic Memory Model

When the resource is acquired/released, it must be well-formed. The well-formedness is resource invariant.

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

. . .

l1 ln

CSL – Formalization

Key ideas:

Threads can only access disjoint resources at the same time.

p q p q

┝ {p2} C2 {q2} ┝ {p1} C1 {q1}

┝ {p1 p2} C1 || C2 {q1 q2}

CSL – Parallel Composition

p q p q

┝ {p2} C2 {q2} ┝ {p1} C1 {q1}

┝ {p1 p2} C1 || C2 {q1 q2}

I() p1 p2 I() q1 q2

r1 rn

. . .

l1 ln

We’ll define I() later.

CSL - Locks

┝ {p} l.acq() {p (l)}

Lock acquire:

Note: do not support reentrant locks

┝ {p (l)} l.rel() {p}

Lock release:

Compare the rules with cons and dispose

ExamplesPut (x):

l.acq();

while( full ){

l.rel();

l.acq();

}

c := x;

full := true;

l.rel();

Get (y):

l.acq();

while( !full ){

l.rel();

l.acq();

}

y := c;

full := false;

l.rel();

(l) = full c _, _ full emp

ExamplesPut (x):

l.acq();

while( full ){

l.rel();

l.acq();

}

(l) = full c _, _ full emp

c := x;

full := true;

l.rel();

{x _, _ }

{x _, _ (l) }

{x _, _ (l) }

{x _, _ }

{x _, _ (l) full }

{x _, _ (l) full }

{x _, _ }

{c _, _ }

{full c _, _ }

{(l) }

{emp }

Examplesget (y):

l.acq();

while( !full ){

l.rel();

l.acq();

}

(l) = full c _, _ full emp

y := c;

full := false;

l.rel();

{emp}

{ (l) }

{(l) }

{ emp }

{(l) full }

{ (l) full }

{c _, _ }

{y _, _ }

{y _, _ (full emp) }

{y _, _ (l)}

{y _, _ }

Examples

x := cons(a, b);

put(x);

get(y);

use(y);

dispose(y);

{x _, _ } put (x) {emp } {emp} get (y) {y _, _ }

{emp emp}

{emp}

{emp} {emp}

{x _, _ }

{emp }

{y _, _ }

{y _, _ }

{emp}{emp emp}

Outline of This Lecture

• Separation Logic Review

• Concurrent Separation Logic (CSL)

• Rely-Guarantee Reasoning (R-G)

• Modular verification of fine-grained concurrency – recent progress

Owicki-Gries MethodSusan Owicki and David Gries, 1975

Non-InterferenceKey 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’)}

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!

Rely-Guarantee Reasoning

• Use rely (R) and guarantee (G) conditions to summarize the behaviors of environments and the thread itself.

R R R

G G G

p q

Rely-Guarantee Reasoning

• R and G: specification of state transitionsexample: x’ x

R R R

G G G

p q

Inference Rules

Inference Rules (2)

Example

< x := x+1 > < x := x+1 >||

{x = 0}

{x = 2}

y := 0; z := 0;

< x := x+1; y := 1; >

< x := x+1; z := 1; >||

{x = 0}

{x = 2}

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 = y+z y = 0} {x = y+z z = 0}

{x = y+z y = 1} {x = y+z z = 1}

{x = y+z y = 0 z = 0}

{x = y+z y = 1 z = 1}

Soundness

• Partial correctness

• Safety

• Preservation of R/G

Outline of This Lecture

• Separation Logic Review

• Concurrent Separation Logic (CSL)

• Rely-Guarantee Reasoning (R-G)

• Modular verification of fine-grained concurrency – recent progress

An Optimistic Non-blocking Stack

ABA problem leads to corrupted stacks

…n Next n Next

Top

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

Threads T1 and T2 are interleaved as follows:

A

B

C

Top

t

next

Timeline

T1:pop(){ t = Top next = t.Next interrupted

resumesCAS(&Top,t,next) succeedsstack corrupted

T2: a = pop(); b = pop(); push(a);

Top

Top

Fix Bugs with Hazard Pointers [Michael04]

pop( ){1 local done, next, t, t1; 2 done = false;3 while (!done) {4 t = Top;5 if (t==null) return null;6 HP[tid] = t;7 t1 := Top;8 if (t == t1){ 9 next = t.Next;10 done = CAS(&Top, t,

next);11 }12 }13 retireNode(t);14 HP[tid] = null;15 return t;

push(x)16 local done, t;

17 done = false;18 while(!done) {19 t = Top;20 x.Next := t;21 done = CAS(&Top,

t, x);22 }23 return true;How to verify its correctness?

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]

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 variablessee [Parkinson et al.’07]

atomic{ -{ I } C -{ I } }

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]

Rely-Guarantee Reasoning

All resources are shared,but access must follow contracts (R-G)!

(R1, G1) (R2, G2)

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}┝

Rely-Guarantee Reasoning

(R1, G1) (R2, G2)

Non-Interference (NI): G2 R1 and G1 R2

Example

[100] := m;

[101] := n;

100 101

G1: [101] = [101]'

R1: [100] = [100]'

G2: [100] = [100]'

R2: [101] = [101]'

Modularity broken!

Rely-Guarantee Reasoning

Expressive for fine-grained concurrency “x cannot decrease”: x' x

Treat everything as shared; no private data Limited support of modularity

Expressiveness and Modularity

Expressiveness of interference

Mo

du

larity (lo

ca

l rea

son

ing

)

CSL

R-G

How to reach here?

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]

SAGL: Separated A-G Logic[Feng et al'07]

Key idea: Separate resources into local and shared!

Private PrivateShared

(R1, G1) (R2, G2)(R2, G2)

SAGL [Feng et al’07]

• 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

(R,G) {(a, p)} C {(r, q)}┝

Example: regained data modularity

[100] := m;

[101] := n;

100 101

-{(emp , 100 _) } -{(emp , 101 _)}

G1: emp

R1: emp

G2: emp

R2: emp

Expressiveness and Modularity

Expressiveness of interference

Mo

du

larity (lo

ca

l rea

son

ing

)

CSL

R-G

SAGL(RGSep)

But still not as modular as CSL!

More expressive for interference:R/G vs. invariants I

More modular:do not specify local data in R/G

R-G with Local Reasoning

Frame rules in CSL:

I {p} ┝ C {q}

I I' {p} ┝ C {q}

No corresponding rules in R-G, SAGL and RGSep.

(R,G) {(a, p)} C {(r, q)}┝

All shared resources must be globally known and specified in R/G.

Allow local reasoning and information hiding.

LRG: Local Rely-Guarantee Reasoning[Feng'09]

a a' S1 S2 S1' S2'

a

a'

Separating conjunction over R/G:

(R0R1,G0G1) {p┝ r} C {p'r}

side conditions omitted(frame)

(R0,G0) {p} ┝ C {p'}

LRG

Another interesting rule for modularity:

(R0R1,G0G1) {p} ┝ C {q} side conditions omitted

(R1,G1) {p} ┝ C {q}

(hide)

Need invariants as fences

R, G, I {p} C {q}┝

Expressiveness and Modularity

Expressiveness of interference

Mo

du

larity (lo

ca

l rea

son

ing

)

CSL

R-G

SAGLRGSep

LRG

R * R'G * G'

HLRG – Adding Histories to R/G[Fu et al.’10]

LRG still not good enough to verify the stack algorithm

Existing approach: heavy use of history variables.

Needs to say “if something happened before in history, then I guarantee that …”

Our solution:

Adding past-tense temporal operators to assertions and R/G

HLRG - Assertion Language

State Assertions:

Trace Assertions:

p, q, R, G::= P | Id | p q | …

P , Q ::= B | E E | P * Q | …

p qTime

p

q

p holds over the historical trace

q holds ever since

qq

q

Time

p = (p true) p

p was once true in the history, including the current trace.

p

p holds at every step in the history

p = ( p)Time

p

…p

pp

p q

Time

p

q

s6s5s4s3s2s1s0

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!

Expressiveness and Modularity

Expressiveness of interference

Mo

du

larity (lo

ca

l rea

son

ing

)

CSL

R-G

SAGLRGSep

LRG HLRG

use trace assertions

Expressiveness and Modularity

Expressiveness of interference

Mo

du

larity (lo

ca

l rea

son

ing

)

CSL

R-G

SAGLRGSep

LRG HLRG

Deny-Guarantee

A separation algebra for interference (D-G)

What do we learn?

We need expressive assertions to specify fine-grained interference!

Invariant I Actions (R,G) Trace assertionsp, p,

Separation gives us local reasoning (modularity)!

All resources as shared

Separate local & shared in R/G

R R' and G G'

(p) (q) …

Take-home messages:

We need expressive assertions to specify fine-grained interference!

Separation gives us local reasoning (modularity)!

Reading Recommendation

• Modular fine-grained concurrency verification Viktor’s Thesis

• Local Rely Guarantee, Xinyu Feng

• HLRG

• Deny-Guarantee Reasoning

top related