Presentation is loading. Please wait.

Presentation is loading. Please wait.

Separation Logic and Concurrency Verification

Similar presentations


Presentation on theme: "Separation Logic and Concurrency Verification"— Presentation transcript:

1 Separation Logic and Concurrency Verification
Xinyu Feng (冯新宇) University of Science and Technology of China

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 num. 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 Concurrent Separation Logic (CSL) Extension of CSL to handle Interrupts

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 ln defined as (ln)  true n l

12 Properties   pemp  p pq  qp pp  p ptrue  p pp  p
(l_)(l_)  false p  ptrue ptrue  p

13 Assertions Model Ownership
[l] := m; {(l  m)} {emp} [l] := m; {???} Ownership cannot be duplicated: (l_)  (l_)(l_)

14 Strength of Separation
{(xn)  (yn)} [x] := m; {(xm)  (yn)} {(xn)  (yn)} [x] := m; {(xm)  (yn)} 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 Concurrent Separation Logic (CSL) Extension of CSL to handle Interrupts

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 Concurrent Separation Logic (CSL)
[O’Hearn 2004] Key ideas: Threads can only access disjoint resources at the same time. p  q {p} C1 {p'} {q} C2 {q'} p q Transfer is logical: no memory copying {p  q} C1 || C2 {p'  q'} C1 and C2 are verified as sequential programs But how to allow threads to share resources?

22 Locks and Critical Regions
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 Note: different locks protect disjoint resources.

23 Concurrent Separation Logic (CSL)
┝ {p} C1 {p'} ┝ {q} C2 {q'} ┝ {p  q} C1 || C2 {p'  q'} l1 ln Memory Model: p q r1   rn

24 CSL (cont’d) p1 r p2 p2 p1  r  p2 p1’ p1’  r  p2 r p2 p2
Each thread can freely access to its local resource.

25 CSL (cont’d) p1 r p2 p2 p1  r  p2 p1  r  p2 l.acq(); C
l.rel(); Suppose (l) = r

26 CSL (cont’d) p1 r p2 p2 p1  r  p2 p1  r  p2 p1’  r  p2 l.acq();
l.rel()

27 CSL (cont’d) p1 r p2 p2 p1  r  p2 p1  r  p2 p1’  r  p2
l.acq(); p1  r  p2 C p1’  r  p2 l.rel(); p1’  r  p2

28 CSL (cont’d) Reasoning about lock acquire/release:
┝ {emp} l.acq() { (l) } Acquiring the lock means getting the ownership of the lock-protected resource. (l) is transferred from shared to local.

29 CSL (cont’d) The rule does not support reentrant locks:
┝ {emp} l.acq() { (l) } {emp} l.acq() {(l) } {(l)  (l) }

30 CSL (cont’d) Reasoning about lock acquire/release:
┝ { (l) } l.rel() { emp } Before releasing the lock, the corresponding resource needs to be well-formed. Releasing the lock means losing the ownership of the resource (which is transferred from local to shared).

31 CSL (cont’d) Reasoning about lock acquire/release:
┝ {emp} l.acq() { (l) } ┝ { (l) } l.rel() { emp } We call this ownership-transfer axiomatic semantics of locks

32 Example: List  = { l  List(top) } getNode(): l.acq(); -{emp} …
l.rel(); -{emp} top r -{emp * List(top)}; -{r(_,_) * List(top)} -{r(_,_) } Sequential verification

33 Outline of This Lecture
Separation Logic Concurrent Separation Logic (CSL) Extension of CSL to handle Interrupts

34 Layering of OS Code B: concurrent code with explicit interrupts
How to certify ???

35 Example: Spinlocks (uniprocessor)
0/1 acquire (l): cli; while([l] == 0){ sti; } [l] := 0; return; // disable Interrupt timer_0: ... switch iret // lock is taken by others [l] :=1; …

36 Example: Spinlocks (uniprocessor)
0/1 acquire (l): cli; while([l] == 0){ sti; } [l] := 0; return; // lock available // acquire lock // enable Interrupt

37 Concurrency with Interrupts: Challenges
IR0 IR1 Asymmetric preemption between handlers and non-handler code Intertwining between threads and handlers Asymmetric synchronization: cli/sti are different from locks

38 Study the problem in 3 steps
Interrupts with Sequential Programs Interrupts with Multi-threaded Programs Adding block/unblock primitives

39 AIM – I : The Machine (program) P ::=(C,S,pc) (data heap) H f1: I1 pc
addu … cli sti iret j f 1 2 f2: I2 r1 r2 r3 rn ih: ISR (register file) R ie (code heap) C (state) S ::=(H,R,ie) ::={f  I}* (program) P ::=(C,S,pc)

40 Example: Teeter-Totter
left right 50 50 timer: if([left] == 0){ print(“right wins!”); iret; } [left] := [left]-1; [right] := [right]+1; while([right] != 0){ cli; [right] := [right]-1; [left] := [left]+1; sti; } print(“left wins!”); Which side wins depends on how frequently the timer interrupt comes.

41 AIM – I : The Memory Model
INV Wellformedness of A; Protocol for sharing B A Memory sti iret cli Non-handler Handler

42 AIM – I : cli/sti B cli B A critical region B sti B A B ie = 1 ie = 0
INV B INV cli B A critical region B Explain memory models: add animation sti B A INV B INV ie = 1 ie = 0

43 Ownership Transfer Semantics for cli/sti
┝ {ie=1} cli {ie=0  INV } ┝ {ie=0  INV} sti {ie=1}

44 AIM – I : handler B A irq B A iret B A B A ie = 1 ie = 0 INV INV INV
Explain memory models: add animation iret B A INV B A INV ie = 1 ie = 0

45 Example: Teeter-Totter
left right INV: m, n. (left  m)  (right  n)  (m+n = 100) m n while(!done){ -{ie=1} cli; -{ie=0  INV} [right] := [right]-1; [left] := [left]+1; done := ([right] == 0); sti; } timer: -{INV} if([left] == 0){ print(“right wins!”); iret; } [left] := [left]-1; [right] := [right]+1; INV is broken in the middle

46 Step 2: Interrupts with Multi-threaded Programs

47 AIM – II : The Machine (program) P ::=(C,S,Q,pc) … (ready. queue) Q
(data heap) H f1: I1 1 2 f2: I2 pc cli sti switch j f r1 r2 r3 rn ih: ISR (register file) R ie (code heap) C (state) S ::=(H,R,ie) ::={f  I}* (program) P ::=(C,S,Q,pc)

48 AIM – II : switch A primitive implemented at layer C
Interrupt must be disabled before executing switch Operational semantics: Put the current thread into ready Q Resume a thread in Q (non-deterministic op) Explain where does switch come from

49 Example: spin locks acquire (l): cli; while([l] == 0){ sti; }
return; switch release (l): cli; [l] := 1; sti; return;

50 Examples Layer A: timer_0: ... switch iret yield: cli switch sti ret
ie = 0: non-preemptive threads ie = 1 & timer_1: non-preemptive threads ie = 1 & timer_0: preemptive threads timer_1: ... iret

51 T1/T2: threads’ private memory
AIM – II : Memory Model INV B A A T1/T2: threads’ private memory C T1 T2 INV1 C: Shared by threads A INV

52 cli/sti t1: C t1: A T1 T2 T1 T2 C A critical region t1: C' t1: A' T1'
INV T1 T2 INV1 T1 T2 t1: cli C A INV1 INV critical region t1: C' t1: A' INV T1' T2 INV1 C' A' INV T1' T2 INV1 t1: sti ie = 1 ie = 0

53 Example: Spinlocks (uniprocessor)
0/1 R -{ emp } -{ R } acquire (l): cli; while([l] == 0){ sti; } [l] := 0; return; Lock l protects the resource R release (l): cli; [l] := 1; sti; return; Don’t talk about the details of abstract specifications

54 Example: Spinlocks (uniprocessor)
0/1 R -{ emp } acquire (l): cli; while([l] == 0){ sti; } [l] := 0; return; INV1: b. (l  b)  (b=0emp  b=1R) Lock and resource R are available Lock is taken; no R for share. A INV C T1 T2 INV1 The lock and the resource R are shared between threads (part of block C). -{ R }

55 Example: Spinlocks (uniprocessor)
0/1 R INV1: b. (l  b)  (b=0emp  b=1R) -{ emp } acquire (l): cli; while([l] == 0){ sti; } [l] := 0; return; -{ emp  INV1  INV}

56 Example: Spinlocks (uniprocessor)
0/1 R INV1: b. (l  b)  (b=0emp  b=1R) -{ emp } acquire (l): cli; while([l] == 0){ sti; } [l] := 0; return; -{ emp  INV1  INV} -{ emp  INV1  INV} -{ emp }

57 Example: Spinlocks (uniprocessor)
0/1 R INV1: b. (l  b)  (b=0emp  b=1R) -{ emp } acquire (l): cli; while([l] == 0){ sti; } [l] := 0; return; -{ emp  INV1  INV} -{ emp  INV1  INV} maybe different state -{ emp } -{ emp  INV1  INV} -{ (l  1)  R  INV} emp  INV1

58 Example: Spinlocks (uniprocessor)
0/1 R INV1: b. (l  b)  (b=0emp  b=1R) -{ emp } acquire (l): cli; while([l] == 0){ sti; } [l] := 0; return; -{ emp  INV1  INV} -{ emp  INV1  INV} -{ emp } -{ emp  INV1  INV} -{ (l  1)  R  INV} emp  INV1 -{ (l  0)  R  INV}

59 Example: Spinlocks (uniprocessor)
0/1 R INV1: b. (l  b)  (b=0emp  b=1R) -{ emp } acquire (l): cli; while([l] == 0){ sti; } [l] := 0; return; -{ emp  INV1  INV } -{ emp  INV1  INV } -{ emp } -{ emp  INV1  INV } Verification is the same as sequential reasoning -{ (l  1)  R  INV } -{ (l  0)  R  INV } INV1 -{ R } -{ R } The verification is sequential!

60 Example: Spinlocks (uniprocessor)
0/1 R INV1: b. (l  b)  (b=0emp  b=1R) -{ emp } acquire (l): cli; while([l] == 0){ sti; } [l] := 0; return; -{ emp  INV1  INV } timer_0: ... switch iret [l] :=1; … -{ emp  INV1  INV } -{ emp } -{ emp  INV1  INV } Verification is the same as sequential reasoning -{ (l  1)  R  INV } -{ (l  0)  R  INV } INV1 -{ R } -{ R } The verification is sequential!

61 switch Thread t1 Thread t2 t2: C t2: A T1 T2 T1 T2 untouched t1: C
INV T1 T2 INV1 T1 T2 untouched t1: switch t1: C t1: A INV1 * INV preserved INV1 INV … sti … cli … switch t1: C' t1: A' INV T1 T2' INV1 t2: C' t2: A' INV T1 T2' INV1 t2: switch Thread t1 Thread t2 ie = 0

62 Local Semantics for switch
┝ {ie = 0  INV1  INV } switch {ie = 0  INV1  INV }

63 Example: Spinlocks (uniprocessor)
0/1 R INV1: b. (l  b)  (b=0emp  b=1R) -{ emp } acquire (l): cli; while([l] == 0){ sti; } [l] := 0; return; -{ emp  INV1  INV } -{ emp  INV1  INV } switch INV1  INV preserved -{ emp } -{ emp  INV1  INV } Verification is the same as sequential reasoning -{ (l  1)  R  INV } -{ (l  0)  R  INV } INV1 -{ R } -{ R } The verification is sequential!

64 Step 3: Adding block/unblock primitives

65 AIM – III : The Machine (program) P ::=(C,S,B,Q,pc) … (ready. queue) Q
f1: f2: ih: r1 1 2 r2 r3 rn (data heap) H (register file) R ie pc R (ready. queue) Q w1 w2 (code heap) C (state) S ::=(H,R,ie) block unblock pc wn B (program) P ::=(C,S,B,Q,pc)

66 AIM – III : block and unblock
block rs put current thread into the block queue B(rs) pick a thread from ready queue to execute unblock rs, rd move a thread from B(rs) to the ready queue put the thread id into rd, put 0 if B(rs) empty no context switching!

67 Examples: locks  l 0/1 R B(l) = Ql acquire_0(l): cli; if ([l] == 0)
block l; else [l] := 0; sti; return; acquire_1(l): cli; while ([l] == 0) block l; [l] := 0; sti; return; release_0(l): local x; cli; unblock l x; if (x == 0) [l] := 1; sti; return; release_1(l): local x; cli; unblock l x; [l] := 1; sti; return;

68 How to interpret block/unblock
Threads block themselves to wait for resources. locks: wait for resources protected by locks condition variables: wait for resources over which the condition holds w1 R1 R2 Rn  ::= {w0  R0, … , wn  Rn} Ri can be emp ! w2 wn B

69 How to interpret block/unblock
INV T1 INV1 ! T1 ? T2 T2 block T1 T1 INV1 INV block unblock T1 INV INV1 T2 ! T2 INV INV1 T1 ! ! switch Thread 1 Thread 2

70 Local Semantics for block/unblock
p  (ie = 0)  INV1  INV0  ┝ { p } block l {p  (l)} p  ie = 0  ┝ {p  (l)} unblock l x {p  (x  0  emp  x = 0  (l))} Blocked thread is released: ownership of (l) is transferred No threads waiting and no ownership transfer

71 Examples: locks  l 0/1 R B(l) = Ql (l) = R
INV1: b, (l  b)  (b=0emp  b=1R) -{ emp } acquire_0(l): cli; if ([l] == 0) block l; else [l] := 0; sti; return; -{ emp } -{ emp  INV1  INV} -{ emp  INV1  INV} -{ emp  INV1  INV  (l) } -{ emp  INV1  INV  R} -{ emp  R} -{ R }

72 Examples: locks  l 0/1 R B(l) = Ql (l) = R
INV1: b, (l  b)  (b=0emp  b=1R) -{ R } release_0(l): local x; cli; unblock l x; if (x == 0) [l] := 1; sti; return; -{ R } -{ R  INV1  INV} -{(x=0  R  x 0  emp)  INV1  INV} -{ R  INV1  INV0} -{ (l  0)  R  INV} -{ (l  1)  R  INV} -{ INV1  INV} -{ emp } -{ emp }

73 Examples: locks  l 0/1 R B(l) = Ql (l) = R (l) = emp
INV1: b, (l  b)  (b=0emp  b=1R) -{ emp } -{ R } acquire_1(l): cli; while ([l] == 0) block l; [l] := 0; sti; return; release_1(l): local x; cli; unblock l x; [l] := 1; sti; return; -{ R } -{ emp }

74 Examples : Condition Variables
wait()/notify() Hoare Style / Brinch-Hanson Style Mesa style Reading material: Feng et al. “Certifying Low-Level Programs with Hardware Interrupts and Preemptive Threads”.

75 Summary Separation logic Concurrent Separation Logic (CSL)
Ownership transfer semantics to thread primitives and interrupt primitives Can be further extended

76 Thank you


Download ppt "Separation Logic and Concurrency Verification"

Similar presentations


Ads by Google