Download presentation
Presentation is loading. Please wait.
Published byChristian Cook Modified over 9 years ago
1
Compositional Verification of Termination-Preserving Refinement of Concurrent Programs Hongjin Liang Univ. of Science and Technology of China (USTC) Joint work with Xinyu Feng (USTC) and Zhong Shao (Yale)
2
Applications of Refinement of Concurrent Programs Correctness of program transformations – Compilers, program optimizations, … T S Compiler Multithreaded Java programs Java bytecode Refinement T ⊑ S : T has no more observable behaviors than S
3
Applications of Refinement of Concurrent Programs Correctness of program transformations – Compilers, program optimizations, … Correctness of concurrent objects & libraries
4
Example – Counter Atomic spec. inc(){ local done, tmp; done = false; while (!done) { tmp = cnt; done = cas(cnt, tmp, tmp+1); } INC(){ } atomic block Impl. in concurrent setting inc || while(true) incINC || while(true) INC ⊑ Correctness: impl refines atomic spec in any context e.g.
5
Applications of Refinement of Concurrent Programs Correctness of program transformations – Compilers, program optimizations, … Correctness of concurrent objects & libraries Correctness of runtime systems & OS kernels – Concurrent garbage collectors, STM algorithms, …
6
Refinement needs to preserve termination! while (true) skip ⋢ skip Compilers of concurrent programs – Need to preserve termination Concurrent objects & libraries – Must satisfy functionality correctness (e.g. linearizability) & “termination” properties (e.g. lock-freedom) No existing logics can verify such a refinement T ⊑ S !
7
Our Contributions Rely-Guarantee-based program logic – For termination-preserving refinement – Compositional verification Applied to verify – Linearizability + lock-freedom – Correctness of optimizations of concurrent prog. New simulation as meta-theory
8
Termination-Preserving Refinement T ⊑ S : More Examples while (true) skipskip ⋢ while (true) skip; print(1); while (true) skip; ⋢ We should avoid T looping infinitely without progress cannot print out 1always print out 1 complete some abstract tasks of S
9
Verifying T ⊑ S : How to avoid T looping infinitely without progress Assign tokens for loops – Consume a token for each iteration € One token to pay for one iteration local i = 0; while (i < 2) i++; print(1); ⊑ € i = 0 i = 1i = 2
10
Verifying T ⊑ S : How to avoid T looping infinitely without progress Assign tokens for loops – Consume a token for each iteration local i = 0; while (true) i++; print(1); ⋢ Never enough tokens!
11
How to compositionally verify T ⊑ S in concurrent settings (Compositionality) T1 || T2 ⊑ S1 || S2 T1S1 ⊑ T2 S2 ⊑ In particular, termination-preservation of individual threads is not compositional
12
Challenge : termination-preservation of individual threads is not compositional print(1); || print(1); S1 || S2 : while (i==0) { i++; } print(1); || while (i==0) { i--; } print(1); T1 || T2 : Both T1 & T2 terminate, but T1 || T2 may not terminate
13
Challenge : termination-preservation of individual threads is not compositional Consider NO environment Need to take env interference into account! How will env affect termination-preservation? Which effects are acceptable? How to change tokens for acceptable env effects? To compositionally verify T ⊑ S in concurrent settings, … Env may delay progress of the current thread. Is it always bad?
14
Env delays progress of current thread – Sometimes acceptable inc(){ 1 local done, tmp; 2 done = false; 3 while (!done) { 4 tmp = cnt; 5 done = cas(cnt, tmp, tmp+1); 6 } } while(true) inc; || INC(){ } Take a snapshot Compare and swap May never progress (complete abstract task INC) since its cas fails infinitely often
15
Env delays progress of current thread – Sometimes acceptable inc(){ 1 local done, tmp; 2 done = false; 3 while (!done) { 4 tmp = cnt; 5 done = cas(cnt, tmp, tmp+1); 6 } } while(true) inc; || INC(){ } Because: The failure of one thread must be caused by the success of another. The system as a whole progresses. Should allow current thread to loop more (i.e. reset tokens) if env progresses
16
Our Ideas Prove termination-preservation of individual threads under env interference – Assign tokens for loops – Consume a token for each iteration Avoid looping infinitely without progress – Could reset tokens when env progresses The system as a whole progresses. So the current thread can loop more.
17
How tokens change : Example of counter inc(){ 1 local done, tmp; 2 done = false; 3 while (!done) { 4 tmp = cnt; 5 done = cas(cnt, tmp, tmp+1); 6 } } cnt 0 inc || inc || inc ⊑ INC || INC || INC € €€ 1 succeededfailed pay for the next iteration Idea: if env progresses, reset the token.
18
Detailed Thread-Local Proof of Counter inc(){ 1 local done, tmp; 2 done = false; 3 while (!done) { 4 tmp = cnt; 5 done = cas(cnt, tmp, tmp+1); 6 } } INC(){ } { cnt = CNT } { cnt = CNT rem(skip) } rem(INC) } abstract tasks to be finished Embed hi-level code in assertions
19
inc(){ 1 local done, tmp; 2 done = false; 3 while (!done) { 4 tmp = cnt; 5 done = cas(cnt, tmp, tmp+1); 6 } } { cnt = CNT rem(INC) } Assign tokens for loops } € { cnt = CNT rem(INC) } pay for one iteration { cnt = CNT rem(INC) ( cnt = tmp )} cnt ≠ tmp { cnt = CNT+1 (done rem(INC)) … } env’s progress – reset tokens ) } € execute hi-level code { cnt = CNT (done rem(skip)) … } ( done rem(INC) ) } € pay for the next iteration
20
NOT a total correctness logic! We ensure low-level preserves termination of high-level – For loops: ensure progress before consuming all tokens Not ensure termination of low-level/high-level code – For loops: not ensure termination before consuming all tokens INC_LOOP(){ while (true) { ; } inc_loop(){ local tmp; while (true) { tmp = cnt; cas(cnt, tmp, tmp+1); } Example – loop a counter ⊑
21
INC_LOOP(){ while (true) { INC; } inc_loop(){ 1 local tmp; 2 while (true) { 3 tmp = cnt; 4 cas(cnt, tmp, tmp+1); 5 } } { cnt = CNT rem(INC_LOOP) } } € { cnt = CNT rem(INC_LOOP) } { cnt = CNT rem(INC_LOOP) … } pay for the next iteration env’s progress – reset tokens { cnt = CNT rem(INC_LOOP) (cnt = tmp cnt ≠ tmp )} € { cnt = CNT+1 rem(INC_LOOP) … } if cas successful € reset tokens since the thrd progresses rem(INC; INC_LOOP) …} execute hi-level code Need one token only
22
Summary of Our Informal Ideas Prove termination-preservation of individual threads under env interference – Assign tokens for loops – Consume a token for each iteration – Could reset tokens when env progresses – Could reset tokens when current thread progresses
23
Our Logic for Verifying T ⊑ S Judgment – R, G: rely/guarantee to describe env interference … and extended with effects on termination-preservation (i.e. whether current thrd is allowed to reset tokens) R, G {p rem(S) } T {q rem(skip)}
24
{p rem(S)} T {q rem(skip)} R, G {p} (T, S) {q}R, G If we can find R, G and q such that then we have: T ⊑ p S {p} (T, S) {q}R, G
25
Compositionality Rules {p} (T1, S1) {r}R, G{r} (T2, S2) {q}R, G {p} (T1;T2, S1;S2) {q}R, G Just like standard Rely/Guarantee rules, e.g. {p1} (T1, S1) {q1}R1, G1 {p2} (T2, S2) {q2}R2, G2 {p1 p2} (T1ǁT2, S1ǁS2) {q1 q2}R1 R2, G1 G2 G2 R1 G1 R2
26
Soundness Theorem If we can find R, G and q such that then we have: T ⊑ p S {p} (T, S) {q}R, G
27
Applications Linearizability & lock-freedom – Counters and its variants – Treiber stack – Michael-Scott lock-free queue – DGLM lock-free queue Correctness of non-atomic objects – Synchronous queue (used in Java 6) Equivalence of optimized algo & original one – Counters and its variants – TAS lock and TTAS lock
28
Conclusion Logic for termination-preserving refinement of concurrent programs – Use tokens for termination-preservation Reset tokens when current thrd or env progresses New rely/guarantee conditions for env interference – Compositionality – Meta-theory: a new simulation http://kyhcs.ustcsz.edu.cn/relconcur/rgsimt
29
BACKUP SLIDES
30
Examples that we cannot verify Linearizability & lock-freedom – Helping HSY elimination-backoff stack – Speculation RDCSS algorithm Technically, we use a forward simulation as meta-theory – Forward-backward simulation?
31
Lock-freedom vs. Obstruction-freedom vs. Wait-freedom How is progress of current thread affected by env? Lock-freedom – Can be affected only if env progresses Obstruction-freedom – Can be affected whatever env does – But when the thread executes in isolation, it must progress Wait-freedom – Cannot be affected
32
Modify our logic to verify obstruction-freedom and wait-freedom Our logic: distinguish whether env progresses – Could reset tokens when env progresses – Lock-freedom Obstruction-freedom – Could reset tokens whenever env does – But when no env, the thread must progress Wait-freedom – Never reset tokens Should also modify definition of T ⊑ S for obstruction-freedom and wait-freedom
33
Lock-Based Algorithms Refinement needs to take fairness into account inc(){ lock(l); cnt++; unlock(l); } INC(){ } inc || inc may not terminate in an unfair execution
34
Hoffmann et al.’s logic for lock-freedom Not prove termination-preservation Need to know the number of threads – Token transfer cnt 0 € € € 1 succeededfailed €€€€ €€ loop: pay one token for one iteration loop: pay one token for one iteration cas: token transfer [LICS’13]
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.