1 / 34

Compositional Verification of Termination-Preserving Refinement of Concurrent Programs

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). Applications of Refinement of Concurrent Programs.

africa
Download Presentation

Compositional Verification of Termination-Preserving Refinement of Concurrent Programs

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Compositional Verification of Termination-Preserving Refinement of Concurrent Programs Hongjin Liang Univ. of Science and Technology of China (USTC) Joint work with XinyuFeng (USTC) and ZhongShao (Yale)

  2. Applications of Refinement of Concurrent Programs • Correctness of program transformations • Compilers, program optimizations, … S Multithreaded Java programs Refinement T ⊑ S : T has no more observable behaviors than S Compiler T Java bytecode

  3. Applications of Refinement of Concurrent Programs • Correctness of program transformations • Compilers, program optimizations, … • Correctness of concurrent objects & libraries

  4. Example – Counter Impl. in concurrent setting Atomic spec. atomic block inc(){ local done, tmp; done = false; while (!done) { tmp = cnt; done = cas(cnt, tmp, tmp+1); } } INC(){ <CNT++> } Correctness: implrefines atomic spec in any context e.g. inc||while(true) inc ⊑ INC||while(true) INC

  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 RefinementT ⊑S : More Examples • while (true) skip • ⋢ • skip • while (true) skip; • print(1); • print(1); • while (true) skip; • ⋢ cannot print out 1 always print out 1 We should avoid T looping infinitely without progress • 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); • ⊑ • print(1); € € i = 1 i = 2 i = 0

  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); • ⋢ • print(1); Never enough tokens!

  11. How to compositionally verify T ⊑Sin concurrent settings T1 ⊑ S1 ⊑ S2 T2  (Compositionality) T1 || T2 ⊑ S1 || S2 In particular, termination-preservation of individual threads is notcompositional

  12. Challenge : termination-preservation of individual threads is notcompositional || print(1); print(1); S1 ||S2: while (i==0) { i--; } print(1); T1 ||T2 : while (i==0) { i++; } print(1); || Both T1 & T2 terminate, but T1 ||T2may not terminate

  13. Challenge : termination-preservation of individual threads is notcompositional • Consider NO environment To compositionally verify T ⊑S in concurrent settings, … Need to takeenv interference into account! How will env affect termination-preservation? Which effects are acceptable? How to change tokens for acceptable env effects? • Env may delay progress of the current thread. Is it always bad?

  14. Envdelays progress of current thread – Sometimes acceptable INC(){ <CNT++> } inc(){ 1 local done, tmp; 2 done = false; 3 while (!done) { 4tmp = cnt; 5 done = cas(cnt, tmp, tmp+1); 6 } } Take a snapshot Compare and swap || while(true) inc; May never progress (complete abstract task INC) since its cas fails infinitely often

  15. Envdelays progress of current thread – Sometimes acceptable Because: The failure of one thread must be caused by the success of another. The system as a whole progresses. INC(){ <CNT++> } inc(){ 1 local done, tmp; 2 done = false; 3 while (!done) { 4tmp = cnt; 5 done = cas(cnt, tmp, tmp+1); 6 } } || while(true) inc; 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 envprogresses • The system as a whole progresses. So the current thread can loop more.

  17. How tokens change : Example of counter inc|| inc|| inc⊑INC|| INC || INC pay for the next iteration failed failed succeeded € € € • Idea: if env progresses, reset the token. inc(){ 1 local done, tmp; 2 done = false; 3 while (!done) { 4tmp = cnt; 5 done = cas(cnt, tmp, tmp+1); 6 } } 0 1 cnt

  18. Detailed Thread-Local Proof of Counter abstract tasks to be finished • inc(){ • 1 local done, tmp; • 2 done = false; • 3 while (!done) { • 4tmp = cnt; • 5 done = cas(cnt, tmp, tmp+1); • 6 } • } INC(){ <CNT++> } { cnt = CNT } rem(INC) } Embed hi-level code in assertions { cnt = CNT  rem(skip) }

  19. inc(){ • 1 local done, tmp; • 2 done = false; • 3 while (!done) { • 4tmp = cnt; • 5 done = cas(cnt, tmp, tmp+1); • 6 } • } Assign tokens for loops { cnt = CNT rem(INC) } pay for one iteration { cnt = CNT rem(INC)} env’s progress – reset tokens •  cnt≠ tmp { cnt = CNT rem(INC) ( cnt = tmp )} execute hi-level code  }  ) } € € pay for the next iteration { cnt = CNT+1 (done  rem(INC))  … } { cnt = CNT  (done  rem(skip))  … } • (done  rem(INC)  ) } €

  20. NOT a total correctness logic! • We ensure low-level preservestermination of high-level • For loops: ensure progress before consuming all tokens • Notensure termination of low-level/high-level code • For loops: not ensure termination before consuming all tokens Example – loop a counter inc_loop(){ localtmp; while (true) { tmp = cnt; cas(cnt, tmp, tmp+1); } } INC_LOOP(){ while (true) { <CNT++>; } } • ⊑

  21. INC_LOOP(){ while (true) { INC; } } • inc_loop(){ • 1 localtmp; • 2 while (true) { • 3tmp = cnt; • 4cas(cnt, tmp, tmp+1); • 5 } • } { cnt = CNT rem(INC_LOOP) } Need one token only { cnt = CNT rem(INC_LOOP)} env’s progress – reset tokens { cnt = CNT rem(INC_LOOP) (cnt = tmp  cnt≠ tmp )} € if cas successful  }  € € { cnt = CNT+1 rem(INC_LOOP)  … } rem(INC; INC_LOOP)  …} execute hi-level code reset tokens since the thrd progresses { cnt = CNT rem(INC_LOOP)  … } pay for the next iteration

  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 envprogresses • Could reset tokens when current thread progresses

  23. Our Logic for Verifying T ⊑ S • Judgment • R, G: rely/guarantee to describe envinterference R, G {p  rem(S) } T{q  rem(skip)} … and extended with effects on termination-preservation (i.e. whether current thrd is allowed to reset tokens)

  24. R, G {p  rem(S)} T {q  rem(skip)} • If we can find R, Gand q such that R, G {p} (T, S){q} R, G {p} (T, S){q} then we have: T⊑p S

  25. Compositionality Rules Just like standard Rely/Guarantee rules, e.g. R1, G1 {p1} (T1,S1) {q1} G2  R1 R2, G2 {p2} (T2,S2) {q2} G1  R2 R1R2, G1G2 {p1p2} (T1ǁT2,S1ǁS2){q1q2} R, G {p} (T1,S1) {r} R, G {r} (T2,S2) {q} R, G {p} (T1;T2,S1;S2) {q}

  26. Soundness Theorem • If we can find R, Gand q such that R, G {p} (T, S){q} then we have: T⊑p S

  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(){ <CNT++> } inc(){ lock(l); cnt++; unlock(l); } inc|| inc may notterminate in an unfair execution

  34. Hoffmann et al.’s logic for lock-freedom [LICS’13] • Not prove termination-preservation • Need to know the number of threads • Token transfer failed failed succeeded € € € € € € € € € loop: pay one token for one iteration 1 0 cnt cas: token transfer

More Related