Greta YorshEran YahavMartin Vechev IBM Research
{ ……………… …… …………………. ……………………. ………………………… } T1() Challenge: Correct and Efficient Synchronization { …………………………… ……………………. … } T2() atomic { ………………….. …… ……………………. ……………… …………………… } T3() atomic Assist the programmer by automatically inferring correct and efficient synchronization
Challenge: Correct and Efficient Synchronization { ……………… …… …………………. ……………………. ………………………… } T1() { …………………………… ……………………. … } T2() { ………………….. …… ……………………. ……………… …………………… } T3() Assist the programmer by automatically inferring correct and efficient synchronization
Challenge Find minimal synchronization that makes the program satisfy the specification Avoid all bad interleaving while permitting as many good interleavings as possible Handle infinite-state programs
Change the abstraction to match the program A Standard Approach: Abstraction Refinement program specification Abstract counter example abstraction Verify Refine
synchronized program A Standard Approach: Abstraction Refinement concurrent program safety specification Abstract counter example state abstraction Verify Restrict Refine Change the program to match the abstraction
Our Approach Synthesis of synchronization via abstract interpretation Compute over-approximation of all possible program executions Add minimal atomics to avoid (over-approximation of) bad interleavings Interplay between abstraction and synchronization Finer abstraction may enable finer synchronization Coarse synchronization may enable coarser abstraction
AGS Algorithm – High Level = true while(true) { Traces = { | ( P ) and S } if (Traces is empty) return implement(P, ) select Traces if (?) { ’ = avoid( ) if ( ’ is false) abort else = ’ } else { ’ = refine( , ) if ( = ‘) abort else = ‘ } Input: Program P, Specification S, Abstraction Output: Program P’ satisfying S under
Avoiding an interleaving By adding atomicity constraints Atomicity predicate [l1,l2] – no context switch allowed between execution of statements at l1 and l2 avoid( ) A disjunction of all possible atomicity predicates that would prevent Example = A 1 B 1 A 2 B 2 avoid( ) = [A 1,A 2 ] [B 1,B 2 ] (abuse of notation)
Example T1 1: x += z 2: x += z T2 1: z++ 2: z++ T3 1: y1 = f(x) 2: y2 = x 3: assert(y1 != y2) f(x) { if (x == 1) return 3 else if (x == 2) return 6 else return 5 }
Example: Parity Abstraction y2 y1 1 Concrete values y2 y1 1 Parity abstraction (even/odd)
Example: Avoiding Bad Interleavings avoid( 1 ) = [z++,z++] = [z++,z++] = true while(true) { Traces={ | ( P ) and S } if (Traces is empty) return implement(P, ) select Traces if (?) { = avoid( ) } else { = refine( , ) }
Example: Avoiding Bad Interleavings avoid( 2 ) =[x+=z,x+=z] = [z++,z++] = [z++,z++] [x+=z,x+=z] = true while(true) { Traces={ | ( P ) and S } if (Traces is empty) return implement(P, ) select Traces if (?) { = avoid( ) } else { = refine( , ) }
Example: Avoiding Bad Interleavings T1 1: x += z 2: x += z T2 1: z++ 2: z++ T3 1: y1 = f(x) 2: y2 = x 3: assert(y1 != y2) = [z++,z++] [x+=z,x+=z] = true while(true) { Traces={ | ( P ) and S } if (Traces is empty) return implement(P, ) select Traces if (?) { = avoid( ) } else { = refine( , ) }
y2 y1 1 parity parity x+=z; x+=z z++; y1=f(x) y2=x assert y1!= y2 T1 T2 T3 x+=z; x+=z z++; y1=f(x) y2=x assert y1!= y2 T1 T2 T3 x+=z; x+=z z++; y1=f(x) y2=x assert y1!= y2 T1 T2 T3 Example: Avoiding Bad Interleavings But we can also refine the abstraction…
y2 y parity interval octagon (a)(b) (c) (d)(e) (f)(g) parity interval octagon x+=z; x+=z z++; y1=f(x) y2=x assert y1!= y2 T1 T2 T3 x+=z; x+=z z++; y1=f(x) y2=x assert y1!= y2 T1 T2 T3 x+=z; x+=z z++; y1=f(x) y2=x assert y1!= y2 T1 T2 T3 x+=z; x+=z z++; y1=f(x) y2=x assert y1!= y2 T1 T2 T3 x+=z; x+=z z++; y1=f(x) y2=x assert y1!= y2 T1 T2 T3 x+=z; x+=z z++; y1=f(x) y2=x assert y1!= y2 T1 T2 T3 x+=z; x+=z z++; y1=f(x) y2=x assert y1!= y2 T1 T2 T3
Quantitative Synthesis Performance: smallest atomic sections Interval abstraction for our example produces the atomicity constraint: ([x+=z,x+=z] ∨ [z++,z++]) ∧ ([y1=f(x),y2=x] ∨ [x+=z,x+=z] ∨ [z++,z++]) Minimal satisfying assignments 1 = [z++,z++] 2 = [x+=z,x+=z]
Choosing between abstraction refinement and program restriction - not always possible to refine/avoid - may try and backtrack AGS Algorithm – More Details Input: Program P, Specification S, Abstraction Output: Program P’ satisfying S under Forward Abstract Interpretation, taking into account for pruning infeasible interleavings = true while(true) { Traces = { | ( P ) and S } if (Traces is empty) return implement(P, ) select Traces if (?) { = avoid( ) } else { = refine( , ) } Backward exploration of invalid Interleavings using to prune infeasible interleavings. Order of selection matters Up to this point did not commit to a synchronization mechanism
Implementability No program transformations (e.g., loop unrolling) Memoryless strategy T1 1: while(*) { 2: x++ 3: x++ 4: } T2 1: assert (x != 1) Separation between schedule constraints and how they are realized Can realize in program: atomic sections, locks,… Can realize in scheduler: benevolent scheduler
0,0 0,1 0,2 2,0 0,0 1,1 0,2 2,1 0,2 2,2 1,2 2,1 1,2 3,2 2,2 y=2 if (y==0) x++ x+=1 if (y==0) y=2 x+=1 T1 0: if (y==0) goto L 1: x++ 2: L: T2 0: y=2 1: x+=1 2: assert x !=y Choosing a trace to avoid
Examples Intuition If we can show disjoint access we can avoid synchronization Requires abstractions rich enough to capture access pattern to shared data Parity Intervals
Example: “Double Buffering” fill() { L1:if (i < N) { L2:Im[Fill][i] = read(); L3: i += 1; L4: goto L1; } L5: Fill ˆ= 1; L6: Render ˆ= 1; L7: i = 0; L8: goto L1; } render() { L1:if (j < N) { L2: write(Im[Render][j]); L3: j += 1; L4: goto L1; } L5: j = 0; L6: goto 1; } int Fill = 1; int Render = 0; int i = j = 0; main() { fill() || render(); } Render Fill
Examples ProgramRefine StepsAvoid Steps Double buffering12 Defragmentation18 3D array update223 Array Removal117 Array Init156
Summary An algorithm for Abstraction-Guided Synthesis Synthesize efficient and correct synchronization Handles infinite-state systems based on abstract interpretation Refine the abstraction and/or restrict program behavior Interplay between abstraction and synchronization Quantitative Synthesis Separate characterization of solution from choosing optimal solutions (e.g., smallest atomic sections)