Ming Fu USTC amp 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 ID: 382002
Download Presentation The PPT/PDF document "Reasoning about Optimistic Concurrency U..." is the property of its rightful owner. Permission is granted to download and print the materials on this web site for personal, non-commercial use only, and to display it on your personal computer provided you do not modify the materials and that you retain all copyright notices contained in the materials. By downloading content from our website, you accept the terms of this agreement.
Slide1
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 ZhangSlide2
What is Optimistic Concurrency?
Increments the shared variable x atomically:
Optimistic Concurrency
Ensuring data consistency by conflict detectionMore efficient than coarse-grained lock-based synchronizationComplex, error-prone and hard to verify
Pessimistic
Optimistic
lock x;
x++;
unlock x;
int
t;
do {
t = x;
}while (!CAS(&x, t, t+1))Slide3
An Optimistic Non-blocking Stack
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; push(x){local done, t;done = false;while(!done) { t = Top; x.Next = t; done = CAS(&Top, t, x);}return true;
Bug#1: t might be a dangling pointer
Bug#2: ABA problem leads to corrupted stacks
…
n
Next
n
Next
TopSlide4
ABA Problem
T1 and T2 do pops and pushes, interleaved as follows:
A
C
B
Top
tnextBCnext(removed)TopAB
t
Top
C
next
(removed)
Timeline
T1:
pop()
{
read t
read next
interrupt
resume
CAS succeeds
stack corrupted
T2:
a = pop();
c = pop();
push(a);Slide5
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;
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;
}Slide6
hazard to 3
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; ACTopB
0
1
2
3
4
HP
5
6
7
tid
reclaimable nodes
removed nodes pointed by hazard pointers
A
A
nodes on stack
removed by 3
hazard to 5
hazard to 7Slide7
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 eventsSlide8
A Program Logic for
History
(
HLRG)Introduces past tense temporal operators into Rely-Guarantee Reasoning!
No history variables
HLRG gives us
the following benefit:Slide9
Extensions in HLRG
Program Traces
Trace-based Operational SemanticsTrace assertions p, q, R, G::= P | Id | p q | …Slide10
p q
Time
p
q
q
q
qp holds over the historical traceq holds ever sinceSlide11
Time
p
p = (p
true) \/ p
p was once true in the history, including the current trace.Slide12
p holds at every step in the history
p =
( p)
Time
p
p
p...Slide13
Rely-Guarantee Reasoning
[Jones'83]
R: invariant of environment’s transitions
G: invariant of the thread’s transitionsp: preconditionq: postcondition
Basic judgment:
R,G
┝ {p} C {q}R/G cannot express directly the temporal properties about the subtle interaction between threads !Slide14
Frame Time & Invariants Rules
R/G, p, q are trace assertions
(
R, G)
┝ {
p
r} C {q r}(FrameT)(R, G)┝ {p} C {q}(R, G)┝ {p} C {q I’}(Inv)(R, G)┝ {p I} C {q}(R G) (I
I’)
Knowledge about history can be added when necessary!
Derived invariants I and I’ can be used for free!
Basic judgment:
R,G
┝
{p} C
{q}Slide15
Verification of pop
reclaimable nodes
removed nodes pointed by hazard pointers
nodes on stack
Shared
=
Top * Stack * RN*HP Removed by a thread t in the historyand pointed by the hazard pointer of thread tid ever since HP[tid] & Top point to A and CAS succeedsTemporal property for each node In RNHP[tid] points to Aremove(A, tid) :removed by 3AC
Top
B0
1
2
3
4
HP
5
6
7
A
Ishazard
to 5
Ishazard
to 7
Shared ResourcesSlide16
Verification of pop
reclaimable nodes
removed nodes pointed by hazard pointers
nodes on stack
Ishazard
(A,
tid) :HP[tid] & Top point to A(HP[tid] points to A) and not (tid updates Top) hazardfree(A, tid) :For all other tid’ , Ishazard(A, tid’) remove(A, tid)removed by 3AC
Top
B
0
1
2
3
4
HP
5
6
7
A
Ishazard
to 5
Ishazard
to 7
Shared Resources
retireNode
(A)Slide17
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; Invariants INV1 for avoiding Bug#1: for all t, tid, ishazard(t, tid) /\ t ≠ null=> t Є Stack \/ t Є RNApply Inv rule with
(R \/ G)
see CONCUR’10 paper for details!Slide18
Conclusion
A Program Logic for History (
HLRG
)R-G reasoning + past tense temporal assertionsSpecifying historical events directly without using history variablesmodular verification (frame rules over space and time)Verifying
the correctness of Michael’s non-blocking stacksSlide19
Thank you!
Questions?