Hongjin Liang and Xinyu Feng University of Science and Technology of China USTC push7 x pop push6 Client code C java util concurrent void push ID: 796166
Download The PPT/PDF document "A Program Logic for Concurrent Objects 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
A Program Logic forConcurrent Objects under Fair Scheduling
Hongjin Liang
and
Xinyu
Feng
University of Science and Technology of China (USTC)
Slide2…
push(7);
x = pop();
…
…
push(6);
…
Client code
C
java.util.concurrent
void push(
int v) { … }
…
int
pop() {
…
}
Concurrent Object
O
T1
T2
T3
push() {
…
}
Slide3Correctness of OLinearizability
Correctness
w.r.t
. functionality
Not talk about termination/liveness properties
Progress propertiesLock-freedom (LF)Wait-freedom (WF)
Obstruction-freedom (OF)Starvation-freedom (SF)Deadlock-freedom (DF)
Non-blocking synchronization- Program Logics: Gotsman et al. POPL’09, Hoffmann et al. LICS’13, …
Blocking synchronization
- Program Logics: ???
[
Herlihy & Shavit]
Slide4SF and DF as Progress Properties
SF
: under fair scheduling,
every
thread can finish its method call
DF: under fair scheduling, there always exists some
thread that can finish its method callT1
T2
T3
f() { …}
Fair scheduling
: every T gets eventually executed[Herlihy and
Shavit
2011]
Liveness property that also disallows live-lock
Slide5Difference between SF and DF
SF
:
every thread
progresses under fair schedulingDF
: only whole-system progresses under fair
schedulinginc() { lock
L; r := cnt; cnt := r+1; unlock
L; }
SF if L is fair lock (e.g. ticket lock, queue lock) DF, but may not be SF
while(true)
inc
();inc();
May
not terminate if the other thread always acquires lock ahead of it
StarvationIt is DF since the whole program keeps finishing method calls.
Slide6Challenges in Verifying SF/DF Objects
Object
impl
takes advantage of fairness assumptionComplicated interdependencies among threads
T releases the lock
T is holding the lock
fair schedT’ requests lock but is blocked
Can T’ get the lock?
Progress of a thread can rely on other threads’ helps
which fairness ensure to happen.
Slide7Challenges: with fairness, progress of a thread can rely on other threads’ helps
L
ook out for
circular reasoning
!
f1() {
x
:= 1; while (y != 0) {}; x
:= 0;}f2(){
y := 1; while (x != 0) {};
y := 0;
}
T1
T2
If:
T2 eventually set
y
to 0Then: I (T1) will set x to 0If: T1 eventually set x to 0
Then: I (T2) will set y to 0
Unsound for liveness reasoning!
rely
rely
guarantee
guarantee
deadlock
Slide8Other Challenges
Possible ad-hoc synchronization
No built-in locks
f1() {
x
:= 1;
while (
y != 0) {}; x := 0;}
f2(){ y := 1;
while (x != 0) {}; y := 0;}
Slide9Other ChallengesPossible ad-hoc synchronization
Disallowing live-lock
Here DF is
not
a safety property!
Unlike earlier work that detects circular waiting for locksOptimistic algorithms: locking + rollback
Cannot be verified using existing workUnifying the verification of SF and DFNever achieved before
Slide10Our Contributions
Program Logic
LiLi
for
Linearizability &
LivenessUnify thread-local reasoning about
DF and SFOne set of inference rules Also support LF and WF algorithms
Examples: Ticket locks, queue locks, TAS locks, two-lock queues, …We’re the first to verify: SF of lock-coupling lists; and DF of optimistic lists and lazy lists
Slide11Our Key Rule for SF/DF Objects
Base on Hoare rule for loop
termination
{p}
while
B
do C {q}
some
well-founded metric decreases at each roundToo strong
in concurrent settings due to env interferenceinc() {
lock
L; r := cnt; cnt
:= r+1;
unlock L;
}
while ( ! succ ) {
succ := cas(L, 0, 1); }
No decreasing metric if blocked// loop-based spin lock :
Slide12Our Key Rule for SF/DF Objects
Base on Hoare rule for loop
termination
Add mechanism for
blocking in SF/DF
{p}
while B do C {q}
some
well-founded metric decreases at each roundblocked but not permanently
unless
Slide13Queue management in banks
Blocking Example: Counter
with
Ticket Lock
inc
() {
local
i, r; i := getAndInc
( next ); while(
i != serving ) {} ; // acquire lock … // critical section
serving := i + 1; // release lock}
the next available ticket
currently being served
next
serving
i
Slide14Blocking Example: Counter with Ticket Lock
inc
() {
local
i
, r; i := getAndInc( next );
while( i != serving ) {} ; // acquire lock … // critical section
serving := i + 1; // release lock
}critical section
serving
next
…
It’s SF, because no permanent blocking:
lock release will eventually happen
(since critical section terminates)blocked thread waits for a
finite sequence of lock release
(since threads requesting the lock form a queue)Blocked
T3
T2
T1
Waiting for T1 to release lock
Slide15Our Idea: Definite Actions D
D
: the actions that will eventually happen, regardless of
env
interferenceE.g. lock release (after acquirement)
Blocked thread waits for a finite sequence of
Ds SF because no permanent blocking
Slide16Definite Actions D
D
is a special action
in the form of
P
Q
Enabled(D) iff P holdsD should be “definite”:
Q should eventually be reached (regardless of env) once enabledE.g. prove critical section terminates
the thread has released lockthe thread has acquired lock
D
Enabled
assume fair scheduling
P
Q
Slide17critical section
serving
next
…
Blocked
T3
T2
T1
T3 will get lock
T2 releases lock
T2 gets lock
D
T1 releases lock
T1 gets lock
D
Enabled
initially
SF
: Blocked thread waits for a
finite
sequence of
D
s.
Enable
f
air
sched
D
-sequence
length is
a decreasing metric
When
sequence
is empty,
thread
can progress.
Slide18Summary of the Ideas for Blocking
More
SF
examples: queue locks, lock-coupling lists
Too strong for
DFD-sequence length decreases
{p} while B do C
{q}
some well-founded metric decreases at each round
blocked but not permanently:
unless
D
Need to prove
D is indeed definite
Slide19DF Counter with TAS Lock
incDF
() {
local
succ, r;
succ := false; while( ! succ ) {
succ := cas(L, 0, 1);
} … // critical section L := 0;
// lock release}
Tickets
TAS lock
: may cause starvation, but can satisfy DF.
lock acquire
Slide20DF: Blocking & delay are intertwined
critical section
T4
T2
T1
Delay
: T1 may fail to get the lock when T2 gets it first.
Blocking
: T4 holds lock, so T1 is waiting for
D
(lock release) from T4.
After T4 finishes
D
, T1 waits for no
D
.
Blocking
: T1 is waiting for
D
(lock release) from T2.
…
T3
D-sequence
length increases!
TAS lock
: all threads compete.
DF allows
this,
but
the delaying threads cannot do infinite delays without finishing method calls.
OK for DF since the delaying thread (T2)
will progress first.
Slide21Elaborate Our “D” Ideas for DF
D-sequence length
can increase if
delayed
DF: we should
ensure no infinite delays before whole-system
progressAssign tokensConsume a token for a delaying action (e.g. cas) Similar ideas have been used to verify LF
[Hoffmann et al LICS’13, Liang et al CSL-LICS’14]
Slide22Elaborate
Our
Loop Rule
{p}
while
B
do C {q}
some
well-founded metric decreases at each rounddelayed but number
of tokens decreasesunless
unless
blocked but D-sequence length decreases
D
Can reason about both DF and SF
Slide23Trickier: Blocking + Delay +
Rollback
add(
e
) {
// all locks are TAS locks
local b := false, p, c; while (!b) { (p, c) := find(e);
lock p; lock c; b := validate(p, c);
if ( !b ) { unlock c; unlock p; }
} … // insert e between p and c unlock c; unlock
p;
}Examples: optimistic lists and lazy lists
It’s deadlock-free.
Problem:
A (TAS) lock consumes a token.
But: A thread may lock a node for an unbounded no. of times.
Need infinite tokens?
Our solution: stratify tokens (see the paper)rollback
retry
Slide24Soundness Theorem for LiLi
O
is
linearizable
w.r.t. A
If ,
then we have:
{p}
O
:
A
D
, R,
G
O is deadlock-free
if R
& G do not
have delaying actions, then O
is
starvation-free
concrete method
impl (e.g. TAS-lock
counter)
abstract atomic spec (e.g. <cnt++>)
Slide25Summary: LiLi for Linearzability
& Liveness
B
locking
: definite actions
Delay: tokens
Unified: By ignoring either or both features, LiLi can be instantiated to support all the four progress properties
non-delay
delaynon-blocking
wait-freedom
lock-freedom
blocking
starvation-freedom
deadlock-freedom
Slide26Thank you!
Slide27Backup Slides
Slide28Obstruction-FreedomProgress when the thread executes in isolation (without interference from
env
)
non-delay
“good” delay
unlimited delay
non-blocking
wait-freedom
lock-freedom
obstruction-freedom
“good” blocking
starvation-freedom
deadlock-freedom
Slide29Obstruction-FreedomProgress when the thread executes in isolation (without interference from
env
)
g1() {
while
(x > 0) { x--; }}g2()
{ while (x < 10) { x++; }}
Slide30Comparisons with earlier token-based work for LF verification
We all assign
-
tokens to loops (pay
at each round)
But LiLi
also assigns -tokens for delaying actionsEarlier work assumes each method has only one delaying action, which is at the linearization point (LP)[Hoffmann et al LICS’13, Liang et al CSL-LICS’14]
incLF(){ local done, r; done := false; while (!done) { r := cnt
; done := cas(cnt, r, r + 1); // LP }}
Slide31Stratify tokens and delaying actions
add(
e
) {
{
(1, 2) … } local b := false, p, c;
while (!b) { (p, c) := find(e); { valid(p, c)
(1, 2)
… … }
lock
p; lock c; { valid(p, c)
(1,
0) …
invalid(p
, c) (1, 2)
… }
b := validate(p, c); if (!b) { unlock c; unlock p; } } … // insert e between p and c unlock c; unlock p;}invalid(p, c) (1,
4) …
}
Could reset
level-1 tokens when delayed by
env’s level-2 action
Level 2: for
add/remove
Level 1: for
lock p & lock c
Slide32Prevent Live-Lock by stratification of
-tokens & delaying actions
Level 2: lock L2
Level 1: lock L1
When g2 locks L2, g1 gets more
1-level -tokensBut 2-level -tokens
do not increase! g1() {
lock L1; while (available(L2)) {
unlock L1; lock L1; } unlock L1;}
g2()
{ lock L2;
while
(available(L1)) {
unlock L2;
lock L2; }
unlock L2;
}g1(); || g2();
Slide33Establish D
Termination of loop (“critical section”) when D is enabled
p’ has one less
-
token than pone token is consumed to start the new iteration
-tokens do not increase, unless delayed by env
{p’} C {p}
D, R, G
{p} while B do C
{p
B}
D
, R,
G
p B
Enabled(D) p
’ * …
Slide34Establish D
Termination of loop (“critical section”) when D is enabled
Global constraints
(at TOP rule)
{p’}
C {p}
D, R, G
{p} while B do
C {p B}
D
, R,
G
p B
Enabled(D) p
’ *
…
{p arem(A) (E)} C {p arem(skip)}
D
, R, G
{p} C :
A
D
, R,
G
p
Enabled(D)
G D (
Enabled(D)
Enabled(D
))
…
Slide35DProgress queue for blocking
{p’}
C
{p}
D
, R, G
{p} while B do
C
{p B}
D
, R, G
p B (Enabled(D)
Q
) p
’ *
p
DProgress(n,
D, Q)DProgress(n, D, Q) stable
Slide36The full rule for while
{p’}
C
{p}
D
, R, G
{p} while B do
C
{p B}
D
, R, G
p B (
Enabled(D)
Q)
p’
*
p
DProgress(n, D, Q)DProgress(n, D, Q) stable
Slide37Tokens for delayATOM rule: Consume
-tokens
q’
k
q : k-level
-tokens decreaseStable(p, R)Reset j-level -
tokens for k-level env
actions where j < kReset -tokens to loop more rounds
{p}
C {q’}
SL
{p} atomic{C} {q}
D
, R,
G
q’ k q
(p
k q) G
Slide38Why
linearizability
and progress together?
Progress-aware abstractions
for concurrent objects
Contextual refinement
O AP
Linearizability O
lin A
Progress P(O)
D, R, G { p }
O
: A
Progress-aware spec
Slide39Progress-aware specs ASF
and
A
DF
O
AP: Assume fair schedulingPreserve termination behaviorsASF : atomic spec
AADF : wrap A with delaying codeO
AP
O lin
A
P
(O
)
D, R, G { p } O
: A
Slide40DF-aware spec
O
wr
(A)O
lin A
DF(O)
D, R, G { p } O
:
A