200 likes | 319 Views
Reasoning about Optimistic Concurrency Using a Program Logic for History. Ming Fu USTC & Yale Joint work with Yong Li, Xinyu Feng , Zhong Shao and Yu Zhang. What is Optimistic Concurrency? . Increments the shared variable x atomically: Optimistic Concurrency
E N D
Reasoning about Optimistic Concurrency Using a Program Logic for History Ming Fu USTC & Yale Joint work with Yong Li, XinyuFeng, ZhongShao and Yu Zhang
What is Optimistic Concurrency? • Increments the shared variable x atomically: • Optimistic Concurrency • Ensuring data consistency by conflict detection • More efficient than coarse-grained lock-based synchronization • Complex, error-prone and hard to verify
An Optimistic Non-blocking Stack Top Next Next n n … • Bug#1: t might be a dangling pointer • Bug#2: ABA problem leads to corrupted stacks
ABA Problem T1 and T2 do pops and pushes, interleaved as follows: T2: a = pop(); c = pop(); push(a); Top Top Top T1: pop() { read t read next interrupt resume CAS succeeds stack corrupted t t A A next C B B B next next C C (removed) (removed) Timeline
Fix Bugs with Hazard Pointers [Michael04] retireNode(t): local i, t; i := 1; while(i<=th_num){ if (i != tid){ t’ := HP[i]; if (t’!= t) i:= i+1; }else i:= i+1; }
nodes on stack • 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; removed nodes pointed by hazard pointers reclaimable nodes 0 HP 1 2 Top hazard to 3 removed by 3 3 tid A A A 4 hazard to 5 5 C hazard to 7 6 B 7
Verifying Stacks with Hazard Pointers using CSL [Matthew POPL07] • pop(){ • 03 while (!done){ • . . . • 06 <HP[tid] = t; HP’[tid] = Req>; • 07 <if (Top != t) continue; else HP’[tid] = Tail(t.Next) >; • 08 <next = t.Next; if (HP’[tid] != Tail(next)) HP’[tid] = Left>; • 09 <done = CAS(&Top, t, next)>; • 10 } • 11 } • . . . • } History variables HP’[tid] and auxiliary codes are used for representing some temporal properties An indirect approach to specifying historical events
A Program Logic for History (HLRG) No history variables Introduces past tense temporal operators into Rely-Guarantee Reasoning! HLRG gives us the following benefit:
Extensions in HLRG • Program Traces • Trace-based Operational Semantics • Trace assertions p, q, R, G::= P | Id | p q | …
p q Time p holds over the historical trace p q q q q q holds ever since
Time p = (p true) \/ p p p was once true in the history, including the current trace.
Time ... p p = ( p) p p p holds at every step in the history
Rely-Guarantee Reasoning [Jones'83] • R: invariant of environment’s transitions • G: invariant of the thread’s transitions • p: precondition • q: postcondition Basic judgment: R,G┝ {p} C{q} R/G cannot express directly the temporal properties about the subtle interaction between threads !
Frame Time & Invariants Rules Basic judgment: R,G┝ {p} C{q} R/G, p, q are trace assertions Knowledge about history can be added when necessary! (R, G)┝ {p I} C{q} (R G) (II’) (Inv) (R, G)┝ {p} C{q} (R, G)┝ {p} C{q I’} (FrameT) (R, G)┝ {p r} C{q r} Derived invariants I and I’ can be used for free!
Verification of pop nodes on stack removed nodes pointed by hazard pointers reclaimable nodes Shared Resources Shared = Top*Stack* RN*HP 0 HP 1 Temporal property for each node In RN 2 remove(A, tid) : removed by 3 3 A A HP[tid] & Top point to A and CAS succeeds Top 4 Ishazard to 5 HP[tid] points to A 5 C Ishazard to 7 6 Removed by a thread t in the history and pointed by the hazard pointer of thread tid ever since B 7
Verification of pop nodes on stack removed nodes pointed by hazard pointers reclaimable nodes Shared Resources Ishazard(A, tid) : 0 HP HP[tid] & Top point to A (HP[tid] points to A) and not (tid updates Top) 1 2 removed by 3 3 retireNode(A) A A Top 4 Ishazard to 5 hazardfree(A, tid) : 5 Ishazard to 7 C For all other tid’ , Ishazard(A, tid’) 6 remove(A, tid) B 7
Applying Inv Rule in the proof pop( ){ … if (t == t1){ {Ishazard(t,tid)} {Ishazard(t,tid) * t |-> _, _} next = t.Next; done = CAS(&Top, t, next); } } retireNode(t); HP[tid] = null; return t; (R \/ G) Apply Inv rule with Invariants INV1 for avoiding Bug#1: for all t, tid, ishazard(t, tid) /\ t ≠ null => t Є Stack \/ t Є RN see CONCUR’10 paper for details!
Conclusion • A Program Logic for History (HLRG) • R-G reasoning + past tense temporal assertions • Specifying historical events directly without using history variables • modular verification (frame rules over space and time) • Verifyingthe correctness of Michael’s non-blocking stacks
Thank you! Questions?
p q Time s0 s1 s2 s3 s4 s5 s6 p q