Presentation is loading. Please wait.

Presentation is loading. Please wait.

A Program Logic for Concurrent Objects under Fair Scheduling Hongjin Liang and Xinyu Feng University of Science and Technology of China (USTC)

Similar presentations


Presentation on theme: "A Program Logic for Concurrent Objects under Fair Scheduling Hongjin Liang and Xinyu Feng University of Science and Technology of China (USTC)"— Presentation transcript:

1 A Program Logic for Concurrent Objects under Fair Scheduling Hongjin Liang and Xinyu Feng University of Science and Technology of China (USTC)

2 … push(7); x = pop(); … push(6); … Client code C java.util.concurrent void push(int v) { … } … int pop() { … } Concurrent Object O T1T2T3 push() { … }

3 Correctness of O Linearizability Correctness w.r.t. functionality Not talk about termination/liveness properties Progress properties Lock-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]

4 SF 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 call T1T2T3 f() { … } Fair scheduling: every T gets eventually executed [Herlihy and Shavit 2011] Liveness property that also disallows live-lock

5 Difference between SF and DF SF: every thread progresses under fair scheduling DF: only whole-system progresses under fair scheduling inc() { 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(); May not terminate if the other thread always acquires lock ahead of it  Starvation It is DF since the whole program keeps finishing method calls.

6 Challenges in Verifying SF/DF Objects Object impl takes advantage of fairness assumption Complicated interdependencies among threads T releases the lock T is holding the lock fair sched T’ 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.

7 Challenges: with fairness, progress of a thread can rely on other threads’ helps Look out for circular reasoning ! f1() { x := 1; while (y != 0) {}; x := 0; } f2(){ y := 1; while (x != 0) {}; y := 0; } T1T2 If: T2 eventually set y to 0 Then: I (T1) will set x to 0 If: T1 eventually set x to 0 Then: I (T2) will set y to 0 Unsound for liveness reasoning! rely guarantee deadlock

8 Other 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; }

9 Other Challenges Possible ad-hoc synchronization Disallowing live-lock Here DF is not a safety property! Unlike earlier work that detects circular waiting for locks Optimistic algorithms: locking + rollback Cannot be verified using existing work Unifying the verification of SF and DF Never achieved before

10 Our Contributions Program Logic LiLi for Linearizability & Liveness Unify thread-local reasoning about DF and SF One 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

11 Our 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 round Too strong in concurrent settings due to env interference inc() { 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 :

12 Our 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 round blocked but not permanentlyunless

13 Queue 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

14 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 } critical section servingnext … 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 T3T2 T1 Waiting for T1 to release lock

15 Our Idea: Definite Actions D D: the actions that will eventually happen, regardless of env interference E.g. lock release (after acquirement) Blocked thread waits for a finite sequence of Ds SF because no permanent blocking

16 Definite Actions D D is a special action in the form of P  Q Enabled(D) iff P holds D should be “definite”: Q should eventually be reached (regardless of env) once enabled E.g. prove critical section terminates the thread has released lock the thread has acquired lock D Enabled assume fair scheduling P Q

17 critical section servingnext … Blocked T3T2 T1 T3 will get lockT2 releases lock T2 gets lock D T1 releases lock T1 gets lock D Enabled initially SF: Blocked thread waits for a finite sequence of Ds. Enable fair sched D-sequence length is a decreasing metric When sequence is empty, thread can progress.

18 Summary of the Ideas for Blocking More SF examples: queue locks, lock-coupling lists  Too strong for DF D-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

19 DF 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

20 DF: Blocking & delay are intertwined critical section T4 T2T1 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.

21 Elaborate Our “D” Ideas for DF D-sequence length can increase if delayed DF: we should ensure no infinite delays before whole-system progress Assign tokens Consume 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]

22 Elaborate Our Loop Rule {p} while B do C {q} some well-founded metric decreases at each round delayed but number of tokens decreases unless blocked but D-sequence length decreases D Can reason about both DF and SF

23 Trickier Trickier: 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

24 Soundness Theorem for LiLi a) O is linearizable w.r.t. A If, then we have: {p} O : A D, R, G b) O is deadlock-free c)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. )

25 Summary: LiLi for Linearzability & Liveness Blocking: definite actions Delay: tokens Unified: By ignoring either or both features, LiLi can be instantiated to support all the four progress properties non-delaydelay non-blockingwait-freedom  lock-freedom  blockingstarvation-freedom  deadlock-freedom

26 Thank you!

27 Backup Slides

28 Obstruction-Freedom Progress 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

29 Obstruction-Freedom Progress when the thread executes in isolation (without interference from env) g1() { while (x > 0) { x--; } g2() { while (x < 10) { x++; }

30 Comparisons 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 actions Earlier 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 }

31 Stratify 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

32 Prevent 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  -tokens But 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();

33 Establish D Termination of loop (“critical section”) when D is enabled p’ has one less  -token than p one 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’ *  …

34 Establish 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 : AD, R, G p   Enabled(D) G  D  (Enabled(D)  Enabled(D)) …

35 DProgress 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

36 The 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

37 Tokens for delay ATOM rule: Consume  -tokens q’  k q : k-level  -tokens decrease Stable(p, R) Reset j-level  -tokens for k-level env actions where j < k Reset  -tokens to loop more rounds {p} C {q’} SL {p} atomic{C} {q}D, R, G q’  k q (p  k q)  G

38 Why linearizability and progress together? Progress-aware abstractions for concurrent objects Contextual refinement O  A P Linearizability O  lin A  Progress P(O)  D, R, G { p } O : A  Progress-aware spec

39 Progress-aware specs A SF and A DF O  A P : Assume fair scheduling Preserve termination behaviors A SF : atomic spec A A DF : wrap A with delaying code O  APO  AP O  lin A  P(O)P(O)  D, R, G { p } O : A 

40 DF-aware spec O  wr(A) O  lin A  DF(O)  D, R, G { p } O : A 


Download ppt "A Program Logic for Concurrent Objects under Fair Scheduling Hongjin Liang and Xinyu Feng University of Science and Technology of China (USTC)"

Similar presentations


Ads by Google