On Sequentializing Concurrent Programs Gennaro Parlato University of













![A first sequentialization: KISS: Keep It Simple and Sequential [Quadeer-Wu, PLDI’ 04] Under-approximation (subset A first sequentialization: KISS: Keep It Simple and Sequential [Quadeer-Wu, PLDI’ 04] Under-approximation (subset](https://slidetodoc.com/presentation_image_h/17e71b1cd25437a3521d67bf24770a95/image-14.jpg)



![LR Sequentialization [ Lal-Reps, CAV’ 08 ] LR Sequentialization [ Lal-Reps, CAV’ 08 ]](https://slidetodoc.com/presentation_image_h/17e71b1cd25437a3521d67bf24770a95/image-18.jpg)















![LR sequentialization as a code-to-code translation main(){ typeg 1 _g 1[K]; typeg 2 _g LR sequentialization as a code-to-code translation main(){ typeg 1 _g 1[K]; typeg 2 _g](https://slidetodoc.com/presentation_image_h/17e71b1cd25437a3521d67bf24770a95/image-34.jpg)

![Lazy Sequentialization (Lazy Approach) [ La Torre-Madhusudan-Parlato, CAV’ 09 ] Lazy Sequentialization (Lazy Approach) [ La Torre-Madhusudan-Parlato, CAV’ 09 ]](https://slidetodoc.com/presentation_image_h/17e71b1cd25437a3521d67bf24770a95/image-36.jpg)


















- Slides: 54
On Sequentializing Concurrent Programs Gennaro Parlato University of Southampton, UK UPMARC 7 th Summer School on Multicore Computing, June 8 -10, 2015
Concurrency for better performace Clock rates are stalling, but Moore’s Law is still alive… • no longer feasible to increase the speed of individual processors • additional gates turned into (caches and) multiple cores ⇒ For better performance programs must be concurrent! ⇒ Concurrency has become an important aspect for many areas of computer science: algorithms, data structures, programming languages, software engineering, testing, verification, …
Writing concurrent programs is DIFFICULT Programmers have to guarantee • correctness of sequential execution of each individual thread • under nondeterministic interferences from other threads (schedules) communication mechanism … T 2 TN threads Rare schedules result in errors that are difficult to find, reproduce, and repair • developers / testers can spend weeks chasing a single bug ⇒ huge productivity problem
Testing remains the most used (and often the only known) paradigm in industry. . . … but is ineffective for concurrent programs: • large number of schedules makes scaling-up difficult • non-deterministic nature of scheduling makes repeatability difficult ⇒ needs to be complemented by automated analyses that handle schedules symbolically
Verification approach develop practical but theoretically well-founded symbolic verification techniques based on the idea of Sequentialization
Sequentialization
Sequentialization: motivations Building verification tools for full-fledged concurrent languages is difficult and expensive. . . … but scalable verification techniques exist for sequential languages • Abstraction • SAT/SMT techniques (i. e. , bounded model checking) • … ⇒ Can we leverage these?
Sequentialization as a code-to-code translation Code-to-code translation from multithreaded recursive programs to sequential programs that preserves reachability shared variables Conc. program T 1 T 2 … “equivalent” TN Sequential program with non determinism Use existing automatic verification techniques designed for sequential programs to analyze concurrent programs
From concurrent to sequential Always possible but can be inefficient • simulate the global behavior (track all locals of each thread) • current techniques do not work What do we want? • avoid the extreme blow-up • track at any point only the locals of one thread What we want is not always possible But it is possible if we restrict behaviors • Bug-finding
Sequentialization: advantages Keep focus on the concurrency aspects of programs, delegate sequential reasoning to an existing analysis tool • code-to-code translation is much easier to implement than a full-fledged analysis tool • simplifies experimentation with different approaches • can be designed to target multiple backends for sequential program analysis
Concurrent (shared-memory) Programs Formed of sequential programs T 1 , … , TN (each possibly with recursive function calls) shared variables … T 1 T 2 TN threads • each program Ti can read and write shared vars • we assume sequential consistency (SC) (writes are immediately visible to all the other programs) • an execution is an interleaving of the executions of each Ti
Anatomy of an execution T 1 T 2 ( l 1’, s 1 ) ( l, s 2 ) ( l 2’, s 2 )
Keep It Simple and Sequentialization
A first sequentialization: KISS: Keep It Simple and Sequential [Quadeer-Wu, PLDI’ 04] Under-approximation (subset of interleavings) Thread creation function call • at context-switches either: - the active thread is terminated or - a not yet scheduled thread is started (by calling its main function) • when a thread is terminated either: - the thread that has called it is resumed (if any) or - a not yet scheduled thread is started
KISS schedules T 1 T 2 T 3 (l 2, s 1) (l 4, s 2) (l 1, s 1) (l , s ) 3 2 T 1 T 2 T 3 (l 5, s 3) (l 1, s 3) Scheduling 1: 1. Start T 1 2. Start T 2 3. Terminate T 2 4. start T 3 5. terminate T 3 6. Resume T 1 Scheduling 2: 1. start T 1 2. start T 2 3. start T 3 4. terminate T 3 5. resume T 2 6. terminate T 2 7. resume T 1 Scheduling 3: 1. start T 1 2. start T 2 3. terminate T 2 4. resume T 1 5. start T 3 6. terminate T 3 7. resume T 1
More on KISS Allows dynamic thread creation in form of asynchronous calls Bounds the number of threads that have been created but not started yet - scheduler nondeterministically starts a thread from this set, or - resumes the last suspended thread (if any) State space: no cross product Context-switches: - does allow an unbounded number of context-switches - does not allow a bounded number context-switches between any two threads (for more than 1 interaction)
Bounded Context-Switching (CS) is essential Switching between threads is allowed only a bounded number of times [Qadeer-Rehof, TACAS’ 05] Systematic bounded CS is useful for bug hunting: most concurrency related bugs manifest themselves within few CS [Musuvathi-Qadeer, PLDI’ 07] Efficient sequentializations for bounded CS • Eager approach [Lal-Reps, CAV’ 08] • Lazy approach [La Torre-Madhusudan-Parlato, CAV’ 09]
LR Sequentialization [ Lal-Reps, CAV’ 08 ]
LR sequentialization: Bounded Round-Robin schedules round 1 round 2 round 3 round k TN-1 TN … T 2 … … T 1 Bounded Round- Robin captures bounded context-switches Schedule: T 2 T 3 T 4 T 1 T 3 T 2 T 1; minimal number of rounds ? ? ?
LR sequentialization: simulation T 1 Sequential program (k-rounds) (l 1, b 1) 1. 2. Guess a 2, …, ak Execute T 1 to completion o Computes - local states l 1, . . , lk, and - global states b 1, …, bk (l 1, a 2) (l 2, b 2) (l 2, a 3) (l 3, b 3) T 2 T 3
LR sequentialization: simulation T 2 T 1 b 1 Sequential program (k-rounds) (l 1, b 1) 1. 2. 3. Guess a 2, …, ak Execute T 1 to completion Pass b 1, …, bk to T 2 (l 1, a 2) b 2 (l 2, b 2) (l 2, a 3) (l 3, b 3) b 3 T 3
LR sequentialization: simulation T 2 T 1 b 1 Sequential program (k-rounds) 1. 2. 3. Guess a 2, …, ak Execute T 1 to completion Pass b 1, …, bk to T 2 o We can dismiss locals of T 1 a 2 b 2 a 3 b 3 T 3
LR sequentialization: simulation T 2 T 1 (l 0’, b 1) b 1 Sequential program (k-rounds) 1. 2. 3. 4. Guess a 2, …, ak Execute T 1 to completion Pass b 1, …, bk to T 2 Execute T 2 to completion 1. Dismiss locals of T 2 2. Dismiss b 1, …, bk (l 1’, c 1) (l 1’, b 2) a 2 b 2 (l 2’, c 2) (l 2’, b 3) a 3 b 3 c 3 T 3
LR sequentialization: simulation T 2 T 1 b 1 Sequential program (k-rounds) c 1 1. 2. 3. 4. Guess a 2, …, ak Execute T 1 to completion Pass b 1, …, bk to T 2 Execute T 2 to completion a 2 b 2 c 2 a 3 b 3 c 3 T 3
LR sequentialization: simulation T 3 T 2 T 1 (l 0’’, c 1) b 1 c 1 Sequential program (k-rounds) 1. 2. 3. 4. 5. 6. Guess a 2, …, ak Execute T 1 to completion Pass b 1, …, bk to T 2 Execute T 2 to completion Pass c 1, …, ck to T 3 Execute T 3 to completion 1. Dismiss locals of T 3 2. Dismiss c 1, …, ck (l 1’, d 1) (l 1’, c 2) a 2 b 2 c 2 (l 1’, d 2) (l 1’, c 3) a 3 b 3 c 3 d 3
LR sequentialization: simulation T 3 T 2 T 1 b 1 c 1 Sequential program (k-rounds) d 1 1. 2. 3. 4. 5. 6. Guess a 2, …, ak Execute T 1 to completion Pass b 1, …, bk to T 2 Execute T 2 to completion Pass c 1, …, ck to T 3 Execute T 3 to completion a 2 b 2 c 2 d 2 a 3 b 3 c 3 d 3
LR sequentialization: simulation T 3 T 2 T 1 b 1 c 1 Sequential program (k-rounds) d 1 1. 2. 3. 4. 5. 6. 7. 8. 1] Guess a 2, …, ak Execute T 1 to completion Pass b 1, …, bk to T 2 Execute T 2 to completion Pass c 1, …, ck to T 3 Execute T 3 to completion Computation iff di = ai+1 i [1, k- a 2 b 2 c 2 d 2 a 3 b 3 c 3 d 3
LR sequentialization: simulation T 3 T 2 T 1 b 1 c 1 Sequential program (k-rounds) d 1 1. Guess a 2, …, ak 2. Execute T 1 to completion 3. Pass b 1, …, bk to T 2 4. Execute T 2 to completion 5. Pass c 1, …, ck to T 3 6. Execute T 3 to completion 7. Computation iff di = ai+1 8. i [1, k 1] • Report an error if a bug occurs during the simulation a 2 b 2 c 2 d 2 a 3 b 3 c 3 d 3
LR seq. as a code-to-code translation for C programs + Pthread CSeq website: users. ecs. soton. ac. uk/gp 4/cseq/ [Fischer-Inverso-Parlato, ASE’ 13]
LR sequentialization as a code-to-code translation … T 1 T 2 TN translates … Concurrent program Sequentialization (code-to-code translation) … F 1() F 2() Simulation functions FN() main() “equivalent” Sequential program with non determinism
LR sequentialization as a code-to-code translation . . . • considers round-robin schedules with k rounds S 0, 1 S 0, 2 - thread → function, run to completion S 1, 1 S 1, 2 • global memory copy for each round - scalar → array S 2, 1 S 2, 2 • context switch → round counter++ SK-1, 1 SK-1, 2 • first thread starts with T 1 T 2 nondeterministic memory contents - other threads continue with content left by predecessor . . . S 0, N . . . S 1, N . . . S 2, N . . . SK-1, N TN
LR sequentialization as a code-to-code translation . . . • considers round-robin schedules with k rounds S 0, 1 S 0, 2 - thread → function, run to completion S 1, 1 S 1, 2 • global memory copy for each round - scalar → array S 2, 1 S 2, 2 • context switch → round counter++ Sk-1, 1 Sk-1, 2 • first thread starts with T 1 T 2 nondeterministic memory contents - other threads continue with content left by predecessor • checker prunes away inconsistent simulations - assume(Si+1, 0 == Si, N); - requires second set of memory copies - errors can only be checked at end of simulation • requires explicit error checks . . . S 0, N . . . S 1, N . . . S 2, N . . . Sk-1, N TN
LR sequentialization as a code-to-code translation //shared vars typeg 1 g 1; typeg 2 g 2; … typeg 1 g 1[K]; typeg 2 g 2[K]; … uint round=1; bool ret=0; //aux vars // context-switch simulation cs() { unsigned int j; j= nondet(); assume(round +j < K); round+=j; if (round==K-1 && nondet()) ret=1; } //thread functions t(){ typex 1 x 1; typex 2 x 2; … stmt 1 ; stmt 2 ; … }… t(){ typex 1 x 1; typex 2 x 2; … cs(); if return; stmt 1[round]; cs(); if return; stmt 2[round]; … }… main(){ … } main_thread(){ … } main(){ … } //next slide
LR sequentialization as a code-to-code translation main(){ typeg 1 _g 1[K]; typeg 2 _g 2[K]; … // first thread starts with non-deterministic memory contents for (i=1; i++; i<K){ _g 1[i] = nondet(); _g 2[i] = nondet(); … } // thread simulations t[0] = main_thread; born[0] = ACTIVE; for (i=0; i++; i<N){ if(born[i]>NO_ACTIVE){ ret=0; round = born[i]; t[i](); } } // consistency check for (i=0; i++; i<K-1){ assume(_g 1[i+1] == g 1[i]); assume(_g 2[i+1] == g 2[i]); … } // error detection assert(err ==0); }
Implementations of variants of LR schema (SMT-based) Corral (SMT-based analysis for Boogie programs) – [ Lal–Qadeer–Lahiri, CAV’ 12 ] – [ Lal–Qadeer, FSE’ 14 ] CSeq (code-to-code translation for C + PThread) – [ Fischer–Inverso–Parlato, ASE’ 13 ] Rek (for Real-time Embedded Software Systems) – [ Chaki–Gurfinkel–Strichman, FMCAD’ 11 ] Storm: implementation for C programs – [ Lahiri–Qadeer–Rakamaric, CAV’ 09 ] – [Rakamaric, ICSE’ 10]
Lazy Sequentialization (Lazy Approach) [ La Torre-Madhusudan-Parlato, CAV’ 09 ]
LR sequentialization is “eager” T 1 a 2 is guessed a 2 may be unreachable EAGER b 1 a 2 b 2 a 3 [Lal, Reps CAV’ 08] T 2 T 3
LR sequentialization does not preserve assertions // shared variables bool blocked=true; int x=0, y=0; blocked=true blocked=false guess x=13 y=0 void thread 1() { while (blocked); x = x/y; if (x%2==1) ERROR; } Inv: y != 0 void thread 2() { x=12; y=2; //unblock thread 2 blocked=false; }
A lazy transformation is desirable A lazy sequential program explores only reachable states of the concurrent program Why is it desirable? • In model-checking it can drastically reduce the explored statespace • Better invariants for deductive verification / abstract interpretation We now illustrate a lazy transformation: [La Torre-Madhusudan-Parlato, CAV’ 09]
Lazy transformation: main idea T 1 o Execute T 1 (l 0, s 0) o Context-switch: store s 1 and abort (l 1, s 1) o Execute T 2 from s 1 o store s 2 and abort T 2 (l’ 1, s 1) store s 1 & abort (l’ 2, s 2) store s 2 & abort
Lazy transformation: main idea T 1 o Re-execute T 1 till it reaches s 1 n May reach a new local state! n Anyway it is correct !! (l’’ 1, s 1) (l’’ 1, s 2) o (l’ 1, s 1) (l 0, s 0) Restart from global s 2 and compute s 3 store s 3 & abort (l 1, s 1) T 2 store s 1 & abort (l’ 2, s 2) store s 2 & abort
Lazy transformation: main idea � T 1 o Switch to T 2 (l 0, s 0) o Execute till it reaches s 2 (l 1, s 1) (l’’ 1, s 1) o Continue computation from global s 3 (l’’ 1, s 2) store s 3 & abort T 2 (l’ 1, s 1) store s 1 & abort (l’ 2, s 2) store s 2 & abort (l’’’ 1, s 2) (l’’’ 1, s 3)
Lazy transformation: main idea � T 1 T 2 s 1 s 2 s 3 s 4 store s 5 store s 1 store s 3 s 2 s 3 store s 2 store s 4 s 5 end
Lazy transformation: features • Explores only reachable states • Preserves invariants across the translation • Tracks local state of one thread at any time • Tracks values of shared variables at context switches (s 1, s 2, …, sk) • Requires recomputation of local states
Lazy sequentialization as a code-to-code translation o Nondet jump to next context where this thread is active … o TN T 1 At last context-switch, T 2 store shared state, abort, and return to main translates … Concurrent program o Guess scheduling Sequentialization o Orchestrate calls to (code-to-code translation) … F 1() F 2() Simulation functions FN() main() threads (Fi) “equivalent” Sequential program with non determinism
Lazy translation for Concurrent Boolean programs • Concurrent Boolean programs • We have implemented an eager and a lazy translator for concurrent Boolean programs - Download: http: //www. cs. uiuc. edu/~madhu/getafix/cbp 2 bp Experiments: Windows NT Bluetooth driver Context switches 1 -adder 1 -stopper eager 1 2 3 4 5 6 N N N 0. 1 0. 3 43. 3 73. 6 930. 0 - 2 -adders 1 -stopper lazy eager 0. 1 0. 2 1. 4 5. 5 20. 2 66. 8 N N N Y Y Y 0. 2 0. 9 135. 9 1601. 0 - 1 -adder 2 -stoppers lazy 0. 1 0. 8 6. 3 2. 6 18. 0 122. 9 eager N N Y Y 0. 1 0. 7 70. 1 597. 2 - 2 -adders 2 -stoppers lazy 0. 1 0. 9 0. 4 2. 9 14. 0 66. 1 eager N N Y Y 0. 2 1. 6 177. 6 out of mem. lazy 0. 1 2. 0 0. 8 7. 5 66. 5 535. 9 • Backend sequential analysis: Get. AFix [La Torre-Madhusudan-Parlato, PLDI’ 09] - BDD-based analysis: it stores summaries recomputations => no multiple thread explorations • Lazy outperforms Eager
More Sequentializations
Lazy translation for Concurrent Boolean programs • Eager and Lazy sequentializations can be extended to parameterized programs: [La Torre-Madhusudan-Parlato, CAV’ 10, FIT’ 12] in 1 T 2 Tm out 1 in 2 in 3 out 2 out 3 Correctness of abstractions of several Linux device drivers
Lazy translation for Concurrent Boolean programs • Eager and Lazy sequentializations can be extended to parameterized programs: [La Torre-Madhusudan-Parlato, CAV’ 10, FIT’ 12] • Delay-bounded scheduling - [Emmi-Qadeer-Rakamaric, POPL’ 11] Programs with asynchronous calls (creating tasks) Each task is executed to completion (no interleaving with other tasks) Sequentialization is according to a DFS scheduler of tasks When dispatched, a task can be delayed to next round – – the total number of delays in a task-creation tree is bounded by k total number of explored rounds is k+1 – The beginning of each round is guessed (eager)
Lazy translation for Concurrent Boolean programs • Eager and Lazy sequentializations can be extended to parameterized programs: [La Torre-Madhusudan-Parlato, CAV’ 10, FIT’ 12] • Delay-bounded scheduling [Emmi-Qadeer-Rakamaric, POPL’ 11] • General sequentialization [Bouajjani-Emmi-Parlato, SAS’ 11] - Programs with asynchronous calls - Tasks can be interleaved with other ones - Sequentialization based on – DAGs of contexts – Composition and compression operations d a b c e – Bound on the size of the DAGs – Generalizes k-rounds Eager e delay bounded-scheduling sequentialization
More Sequentializations • Eager and Lazy sequentializations can be extended to parameterized programs: [La Torre-Madhusudan-Parlato, CAV’ 10, FIT’ 12] • Delay-bounded scheduling [Emmi-Qadeer-Rakamaric, POPL’ 11] • General sequentialization [Bouajjani-Emmi-Parlato, SAS’ 11] • Scope-bounded sequentialization [La Torre-Napoli-Parlato, FSTTCS’ 12] • Budget-bounded sequentialization [Abdulla-Atig- Rezine-Stenman, FMCAD’ 12] • Sequentialization for proving correctness [Garg-Madhusudan, TACAS’ 11] • Bounded-phase sequentialization of message passing programs [Bouajjani-Emmi, TACAS’ 12] • Eager sequentialization for periodic programs [Chaki-Gurfinkel-Sinha, FMCAD’ 14], [Chaki-Gurfinkel-Strichman, FMCAD’ 13] • …
Conclusions
Conclusions Sequentialization is an effective approach to analyze concurrent programs – – – Fast prototyping Re-use of mature technologies (tools designed for sequential programs) Code-to-code translation Presented translations: – – – keep track only of the local state of the current thread (no cross product) Keep track of a finite number of copies of shared states thread creation is implemented with calls • KISS is a lazy sequentialization that allows an unbounded number of context-switches, but does not allow a bounded number context-switches between any two threads • Bounded context-switches: - Eager translations require guessing of values of the shared variables and may explore unreachable states - Lazy translations preserve the invariants and introduces many recursive calls (thread re-computations)
Tomorrow’s lecture Sequentializations for Bounded Model Checking backends: • Lazy-CSeq • MU-Cseq [ Inverso-Tomasco-Fischer-La Torre-Parlato, CAV’ 14 ] [ Tomasco-Inverso-Fischer-La Torre-Parlato, TACAS’ 15 ] framework for developing sequentialization of concurrent C programs : users. ecs. soton. ac. uk/gp 4/cseq/






















































