Upload
others
View
5
Download
0
Embed Size (px)
Citation preview
Synthesis for Concurrency
1
Martin Vechev ETH Zurich
(joint work with Eran Yahav, Greta Yorsh)
Concurrency is Everywhere
Concurrency is Everywhere Unreliable
2003 Northeast Blackout
concurrency error triggers massive power outage economic effect : ~ 6 billion $USD
val popRight() { while (true) { rh = RightHat; lh = LeftHat; if (rh->R == rh) return "empty"; if (rh == lh) { if (DCAS(&RightHat, &LeftHat, rh, lh, Dummy, Dummy)) return rh->V; } else { rhL = rh->L; if (DCAS(&RightHat, &rh->L, rh, rhL, rhL, rh)) { result = rh->V; rh->R = Dummy; return result; }}}
“Even better DCAS-based concurrent deques”, DISC 2000
Unreliable Concurrency: Data Structures
val popRight() { while (true) { rh = RightHat; lh = LeftHat; if (rh->R == rh) return "empty"; if (rh == lh) { if (DCAS(&RightHat, &LeftHat, rh, lh, Dummy, Dummy)) return rh->V; } else { rhL = rh->L; if (DCAS(&RightHat, &rh->L, rh, rhL, rhL, rh)) { result = rh->V; rh->R = Dummy; return result; }}}
“Even better DCAS-based concurrent deques”, DISC 2000
Bad News: 2 errors in < 20 lines of code
Unreliable Concurrency: Data Structures
int take() long b = bot-1; item_t *q = wsq; bot = b long t = top if (b < t) { bot = t; return EMPTY; } task = q->ap[b%q->sz]; if (b > t) return task if (!CAS(&top,t,t+1)) return EMPTY; bot = t + 1; return task;
void push(int task) long b = bot; long t = top; item_t *q = wsq; if (b–t q->sz–1){ wsq = expand(); q = wsq; } q->ap[b%q->sz]=task; bot = b+1;
int steal() long t = top; long b = bot; item_t *q = wsq; if (t b) return EMPTY; task=q->ap[t%q->sz]; if (!CAS(&top,t,t+1)) return ABORT; return task;
7
Unreliable Concurrency: Weak Memory Models
int take() long b = bot-1; item_t *q = wsq; bot = b long t = top if (b < t) { bot = t; return EMPTY; } task = q->ap[b%q->sz]; if (b > t) return task if (!CAS(&top,t,t+1)) return EMPTY; bot = t + 1; return task;
void push(int task) long b = bot; long t = top; item_t *q = wsq; if (b–t q->sz–1){ wsq = expand(); q = wsq; } q->ap[b%q->sz]=task; bot = b+1;
int steal() long t = top; long b = bot; item_t *q = wsq; if (t b) return EMPTY; task=q->ap[t%q->sz]; if (!CAS(&top,t,t+1)) return ABORT; return task;
8
Unreliable Concurrency: Weak Memory Models
9
bool add(int key) { Entry *pred,*curr,*entry restart: locate(pred,curr,key) k = (curr->key == key) if (k) return false entry = new Entry() entry->next = curr val=CAS(&pred->next, curr,0,entry,0) if (val) goto restart return true }
bool remove(int key) { Entry *pred,*curr,*r restart: locate(pred,curr,key) k = (curr->key ≠ key) if (k) return false <r,m> = curr->next lval=CAS(&curr->next, r,m,r,1) if (lval) goto restart pval=CAS(&pred->next, curr,0,r,0) if (pval) goto restart return true }
Concurrent Set Algorithm
bool contains(int key) { Entry *pred,*curr locate(pred,curr,key) k = (curr->key == key) if (k) return false return true }
10
bool add(int key) { Entry *pred,*curr,*entry restart: locate(pred,curr,key) k = (curr->key == key) if (k) return false entry = new Entry() entry->next = curr val=CAS(&pred->next, curr,0,entry,0) if (val) goto restart return true }
bool remove(int key) { Entry *pred,*curr,*r restart: locate(pred,curr,key) k = (curr->key ≠ key) if (k) return false <r,m> = curr->next lval=CAS(&curr->next, r,m,r,1) if (lval) goto restart pval=CAS(&pred->next, curr,0,r,0) if (pval) goto restart return true }
Concurrent Set Algorithm
bool contains(int key) { Entry *pred,*curr locate(pred,curr,key) k = (curr->key == key) if (k) return false return true }
The Good • New algorithm • Fine-grained synchronization (CAS)
11
bool add(int key) { Entry *pred,*curr,*entry restart: locate(pred,curr,key) k = (curr->key == key) if (k) return false entry = new Entry() entry->next = curr val=CAS(&pred->next, curr,0,entry,0) if (val) goto restart return true }
bool remove(int key) { Entry *pred,*curr,*r restart: locate(pred,curr,key) k = (curr->key ≠ key) if (k) return false <r,m> = curr->next lval=CAS(&curr->next, r,m,r,1) if (lval) goto restart pval=CAS(&pred->next, curr,0,r,0) if (pval) goto restart return true }
Concurrent Set Algorithm
bool contains(int key) { Entry *pred,*curr locate(pred,curr,key) k = (curr->key == key) if (k) return false return true }
The Good • New algorithm • Fine-grained synchronization (CAS)
The Bad • Can you understand what it does? • Can you show it is correct?
12
bool add(int key) { Entry *pred,*curr,*entry restart: locate(pred,curr,key) k = (curr->key == key) if (k) return false entry = new Entry() entry->next = curr val=CAS(&pred->next, curr,0,entry,0) if (val) goto restart return true }
bool remove(int key) { Entry *pred,*curr,*r restart: locate(pred,curr,key) k = (curr->key ≠ key) if (k) return false <r,m> = curr->next lval=CAS(&curr->next, r,m,r,1) if (lval) goto restart pval=CAS(&pred->next, curr,0,r,0) if (pval) goto restart return true }
Concurrent Set Algorithm
bool contains(int key) { Entry *pred,*curr locate(pred,curr,key) k = (curr->key == key) if (k) return false return true }
The Good • New algorithm • Fine-grained synchronization (CAS)
The Bad • Can you understand what it does? • Can you show it is correct?
The Ugly • How did you get it? • Anything repeatable? • Any other similar algorithms?
13
bool add(int key){ atomic Entry *pred,*curr,*entry locate(pred,curr,key); k = (curr->key == key) if (k) return false entry = new Entry() entry->next = curr pred->next = entry return true }
bool remove(int key){ atomic Entry *pred,*curr,*r locate(pred,curr,key) k = (curr->key ≠ key) if (k) return false r = curr->next pred->next = r return true }
Sequential Set Algorithm
bool contains(int key) { atomic Entry *pred,*curr locate(pred,curr,key) k = (curr->key == key) if (k) return false return true }
14
bool add(int key){ atomic Entry *pred,*curr,*entry locate(pred,curr,key); k = (curr->key == key) if (k) return false entry = new Entry() entry->next = curr pred->next = entry return true }
bool remove(int key){ atomic Entry *pred,*curr,*r locate(pred,curr,key) k = (curr->key ≠ key) if (k) return false r = curr->next pred->next = r return true }
Sequential Set Algorithm
bool contains(int key) { atomic Entry *pred,*curr locate(pred,curr,key) k = (curr->key == key) if (k) return false return true }
• Understandable • Proving correctness easier
15
Sequential to Highly Concurrent bool add(int key){ atomic Entry *pred,*curr,*entry locate(pred,curr,key); k = (curr->key == key) if (k) return false entry = new Entry() entry->next = curr pred->next = entry return true }
bool remove(int key){ atomic Entry *pred,*curr,*r locate(pred,curr,key) k = (curr->key ≠ key) if (k) return false r = curr->next pred->next = r return true }
16
bool add(int key) { Entry *pred,*curr,*entry restart: locate(pred,curr,key) k = (curr->key == key) if (k) return false entry = new Entry() entry->next = curr
val=CAS(&pred->next,curr,0,entry,0) if (val) goto restart return true }
bool remove(int key) { Entry *pred,*curr,*r restart: locate(pred,curr,key) k = (curr->key ≠ key) if (k) return false <r,m> = curr->next
lval=CAS(&curr->next, r,m,r,1) if (lval) goto restart
pval=CAS(&pred->next,curr,0,r,0) if (pval) goto restart return true }
Sequential to Highly Concurrent bool add(int key){ atomic Entry *pred,*curr,*entry locate(pred,curr,key); k = (curr->key == key) if (k) return false entry = new Entry() entry->next = curr pred->next = entry return true }
bool remove(int key){ atomic Entry *pred,*curr,*r locate(pred,curr,key) k = (curr->key ≠ key) if (k) return false r = curr->next pred->next = r return true }
17
bool add(int key) { Entry *pred,*curr,*entry restart: locate(pred,curr,key) k = (curr->key == key) if (k) return false entry = new Entry() entry->next = curr
val=CAS(&pred->next,curr,0,entry,0) if (val) goto restart return true }
bool remove(int key) { Entry *pred,*curr,*r restart: locate(pred,curr,key) k = (curr->key ≠ key) if (k) return false <r,m> = curr->next
lval=CAS(&curr->next, r,m,r,1) if (lval) goto restart
pval=CAS(&pred->next,curr,0,r,0) if (pval) goto restart return true }
Sequential to Highly Concurrent bool add(int key){ atomic Entry *pred,*curr,*entry locate(pred,curr,key); k = (curr->key == key) if (k) return false entry = new Entry() entry->next = curr pred->next = entry return true }
bool remove(int key){ atomic Entry *pred,*curr,*r locate(pred,curr,key) k = (curr->key ≠ key) if (k) return false r = curr->next pred->next = r return true }
???
Bridging the Gap
Find small repeatable transformations NO magic insights
Combination of manual and automatic
transformations
18
Transformations
13
Removing redundant atomicity
Reordering statements
Optimistic concurrency
Add synchronization meta-data
s1 s2
s3 s4
s1 s2
s3 s4
If (validate) update else restart
read
s1 s2
s3 s4
s2 s1
s3 s4
s3 s4
read update
s1 s2
s1 If (t > 0) s2
s3 s4
Transformations
13
Removing redundant atomicity
Reordering statements
Optimistic concurrency
Add synchronization meta-data
s1 s2
s3 s4
s1 s2
s3 s4
If (validate) update else restart
read
s1 s2
s3 s4
s2 s1
s3 s4
s3 s4
read update
s1 s2
s1 If (t > 0) s2
s3 s4
Machine
Machine
Machine + Human
Only Human
Synthesis Process
verifier program
yes/counterexample synthesizer
Schema
• Exploration • Validation
Machine
Human
Checked Algorithms
Program Synthesis
15
verifier program
yes/counterexample synthesizer
Machine
analyze program
Program Synthesis
15
verifier program
yes/counterexample synthesizer
Machine
analyze program
Program Synthesis
15
verifier program
yes/counterexample synthesizer
Machine
analyze program
Program Synthesis
15
verifier program
yes/counterexample synthesizer
Machine
analyze program
Program Synthesis
15
verifier program
yes/counterexample synthesizer
Machine
propagate correctness
Program Synthesis
15
verifier program
yes/counterexample synthesizer
Machine
analyze program
Program Synthesis
15
verifier program
yes/counterexample synthesizer
Machine
propagate incorrectness
Program Synthesis
15
verifier program
yes/counterexample synthesizer
Machine
30
Sequential To Concurrent
Schema
Correct Algorithm
DCAS
Sequential
DCAS CAS CAS with LOCKS
Priority Queue
Stack
CAS/DCAS
… …
Michael (PODC’02)
Heller et al. (OPODIS’05)
Trieber Stack
Existing Algorithm
New Algorithm
locate(pred,curr,key)
31
step 1: Optimistic Concurrency [Kung & Robinson’81]
bool remove(int key){ Entry *pred,*curr,*r atomic locate(pred,curr,key) k = (curr->key ≠ key) if (k) return false r = curr->next pred->next = r return true }
bool remove(int key){ Entry *pred,*curr,*r restart:
Read atomic
if (validate) {
Update } goto restart }
k = (curr->key ≠ key) if (k) return false r = curr->next pred->next = r return true
Update
Read
locate(pred,curr,key)
step 1: Optimistic Concurrency [Kung & Robinson’81]
bool remove(int key){ Entry *pred,*curr,*r atomic locate(pred,curr,key) k = (curr->key ≠ key) if (k) return false r = curr->next pred->next = r return true }
bool remove(int key){ Entry *pred,*curr,*r restart: locate(pred,curr,key) atomic
if (validate) { k = (curr->key ≠ key) if (k) return false r = curr->next pred->next = r return true } goto restart }
k = (curr->key ≠ key) if (k) return false r = curr->next pred->next = r return true
Update
Read
step 2: Run Tool
33
No correct completion found
Insufficient information to write a validation condition
bool remove(int key){ Entry *pred,*curr,*r restart: locate(pred,curr,key) atomic if (validate) { k = (curr->key ≠ key) if (k) return false r = curr->next pred->next = r return true } goto restart }
Synthesizer looks for expressions to fill the validate hole
( (pred | curr) (->next)? == (pred | curr) (->next)? ) | true
step 2: Examine Counterexample
34
head
add(4) starts
1
tail
pred curr
remove(1) executes
add(4) ends
1
head tail
pred curr
4 1
head tail
How to deal with removed nodes?
Thread 1: Thread 2: add(4) remove(1)
Addition of key 4 is lost
But What Now ?
Space
Synchronization Time
36
step 3: Synchronization Metadata
key next key next marked
REMOVE = { R1: k = (curr->key ≠ key) R2: if (k) return false R3: curr->marked = true R4: mp = pred->marked R5: mc = curr->marked R6: val= (pred->next == curr) ( mp)? ( mc)? R7: if (val) goto restart R8: r = curr->next R9: pred->next = r }
OBJECT OBJECT
step 4: Run Synthesis
37
bool remove(int key) { Entry *pred,*curr,*r restart: locate(pred,curr,key) REMOVE return true } REMOVE = { R1: k = (curr->key ≠ key) R2: if (k) return false R3: curr->marked = true R4: mp = pred->marked R5: mc = curr->marked R6: val= (pred->next == curr) ? ( mp) ? ( mc) R7: if (val) goto restart R8: r = curr->next R9: pred->next = r }
bool remove(int key) { Entry *pred,*curr,*r restart: locate(pred,curr,key) REMOVE return true } REMOVE = { k = (curr->key ≠ key) if (k) return false curr->marked = true r = curr->next atomic mp = pred->marked val=(pred->next==curr) mp if (val) goto restart pred->next = r }
Synthesis
38
bool add(int key) { Entry *pred,*curr,*entry restart: locate(pred,curr,key) k = (curr->key == key) if (k) return false entry = new Entry() entry->next = curr val=CAS(&pred->next, curr,0,entry,0) if (val) goto restart return true }
bool remove(int key) { Entry *pred,*curr,*r restart: locate(pred,curr,key) k = (curr->key ≠ key) if (k) return false <r,m> = curr->next lval=CAS(&curr->next, r,m,r,1) if (lval) goto restart pval=CAS(&pred->next, curr,0,r,0) if (pval) goto restart return true }
Result (pldi’08)
bool contains(int key) { Entry *pred,*curr locate(pred,curr,key) k = (curr->key == key) if (k) return false return true }
39
Concurrent Set Algorithms Recap
DCAS
Sequential
DCAS CAS CAS with LOCKS
Priority Queue
Stack
CAS/DCAS
… …
Michael (PODC’02)
Heller et al. (OPODIS’05)
Trieber Stack
Schema
Correct Algorithm
Existing Algorithm
New Algorithm
Synthesis Process
verifier program
yes/counterexample synthesizer
Schema
• Exploration • Validation
Machine
Human
Checked Algorithms
Key questions
Are schemas a natural input for a designer ? can be difficult for designers, prefer programs
Why are search and verification separate ? Verifier overwhelmed with many incorrect or similar
programs
Can synchronization inference be automated ? atomicity, ordering, space (big challenge)
27
Another approach: verification-driven
The input to synthesizer is a program synthesizer “repairs” or “fixes” an incorrect program
Verifier does synthesis can output a program, not just yes/no
Automates synchronization inference some synchronization (but not all, e.g. space is not)
28
Synthesis Process
Human
Checked Algorithms Program
verifier extended to do synthesis
Synthesizer “repairs” the program by synthesizing synchronization
Synthesizer produces various repairs versions of the program
Challenge
Find minimal synchronization that makes the program satisfy the specification Avoid all bad schedules while permitting as many
good schedules as possible
Assumption: we can prove that serial executions
satisfy the specification Interested in bad behaviors due to concurrency
Handle infinite-state programs
30
Abstraction-Guided Synthesis of Synchronization
Synthesis of synchronization via abstract interpretation Compute over-approximation of all possible program
executions Add minimal synchronization to avoid
(over-approximation of) bad schedules Interplay between abstraction and synchronization Finer abstraction may enable finer synchronization Coarse synchronization may allow coarser abstraction
31
Change the abstraction to match the program
A Standard Approach: Abstraction Refinement
Program P
Specification S
Abstract counter example
Abstraction
Abstraction Refinement
Abstract counter example
Verify
Valid
32
Program P
Abstract counter example
Abstraction Refinement
Change the program to match the abstraction
ϕ
Verify
Abstraction-Guided Synthesis [VYY-POPL’10]
Program Restriction
Implement P’
Abstract counter example
33
Specification S
Abstraction
AGS Algorithm – High Level
ϕ = true
while(true) {
BadTraces = {π | π ∈ (P ∩ ϕ) and π S }
if (BadTraces is empty) return implement(P,ϕ)
select π ∈ BadTraces
if (?) {
ψ = avoid(π)
if (ψ ≠ false) ϕ = ϕ ∧ ψ
else abort
} else {
’ = refine(, π)
if (’≠ ) = ’
else abort
}
}
Input: Program P, Specification S, Abstraction
Output: Program P’ satisfying S under ’
34
Avoid and Implement
Desired output – program satisfying the spec Constraint has to be implementable in the program
Implementation mechanism guides the choice of constraint language
Implementation mechanisms Atomic sections [POPL’10] Conditional critical regions (CCRs) [TACAS’09] Memory fences (for relaxed memory models)
[FMCAD’10 + PLDI’11] Barriers [SAS’13] …
35
Avoiding a schedule with atomic sections
Adding atomicity constraints Atomicity predicate [l1,l2] –statements at l1 and l2
must execute together atomically avoid(π) A disjunction of all possible atomicity predicates
that would prevent π Captures all ways to avoid π using atomic sections
36
avoid(π) = { [label(πi),label(πj)] | 0 i < |π|, j > i + 1. tid(πi) = tid(πj) s.t. k.i < k < j, tid(πi)tid(πk) }
Avoid with atomicity constraints
37
1,1
2,1
3,1
A1
A2
2,2
B1
1,2
B1
2,3 3,2
B1
3,3
B2 A2
A1
1,3
B2
A2 B2 A1
Thread A 1: A1 2: A2
Thread B 1: B1 2: B2
π = A1 B1 A2 B2
avoid(π) = [A1,A2] [B1,B2]
Avoiding the good with the bad
ψ = avoid(π) Enforcing ψ avoids any abstract trace π’
such that π’ ψ Potentially avoiding “good traces” as well
38
A1 B1 A2 A3 1 1
A1 B1 A2 A3 2
2
avoid(1) = [A1,A2]
Simple Example
Initially x = z = 0 Every single statement is atomic
39
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 }
atomic
Example: Concrete Values
0 2 3
1 2 3 4 5
4
6
y2
y1
1
Concrete values
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 }
x += z; x += z; z++;z++;y1=f(x);y2=x;assert y1=5,y2=0
z++; x+=z; y1=f(x); z++; x+=z; y2=x;assert y1=3,y2=3 …
40
Example: Parity Abstraction
0 2 3
1 2 3 4 5
4
6
y2
y1
1
Concrete values
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 }
x += z; x += z; z++;z++;y1=f(x);y2=x;assert y1=Odd,y2=Even
0 2 3
1 2 3 4 5
4
6
y2
y1
1
Parity abstraction (even/odd)
41
Example: Avoiding Bad Interleavings
avoid(π1) = [z++,z++]
ϕ = [z++,z++] ϕ = true
ϕ = true while(true) { BadTraces={π|π∈(P ∩ ϕ) and π S } if (BadTraces is empty) return implement(P,ϕ) select π ∈ BadTraces if (?) { ϕ = ϕ ∧ avoid(π) } else { = refine(, π) } }
42
z++
z++
T1 x+=z x+=z
T3 y1=f(x)
y2=x
Showing only states leading to bad states
Example: Avoiding Bad Interleavings
avoid(π2) =[x+=z,x+=z]
ϕ = [z++,z++] ϕ = [z++,z++]∧[x+=z,x+=z]
ϕ = true while(true) { BadTraces={π|π∈(P ∩ ϕ) and π S } if (BadTraces is empty) return implement(P,ϕ) select π ∈ BadTraces if (?) { ϕ = ϕ ∧ avoid(π) } else { = refine(, π) } }
43
x+=z
x+=z
T3 y1=f(x)
y2=x
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] 44
ϕ = true while(true) { BadTraces={π|π∈(P ∩ ϕ) and π S } if (BadTraces is empty) return implement(P,ϕ) select π ∈ BadTraces if (?) { ϕ = ϕ ∧ avoid(π) } else { = refine(, π) } }
0 2 3
1 2 3 4 5
4
6
y2
y1
1
parity
0 1 2 3
1 2 3 4 5
4
6
0 1 2 3
1 2 3 4 5
4
6 parity parity
x+=z; x+=z z++; z++; y1=f(x) y2=x assert y1!= y2
T1
T2
T3
x+=z; x+=z z++; z++; y1=f(x) y2=x assert y1!= y2
T1
T2
T3
x+=z; x+=z z++; z++; y1=f(x) y2=x assert y1!= y2
T1
T2
T3
Example: Avoiding Bad Interleavings
But we can also change the abstraction…
45
0 2 3
1 2 3 4 5
4
6
y2
y1
1
0 1 2 3
1 2 3 4 5
4
6
0 1 2 3
1 2 3 4 5
4
6
parity
interval
octagon
0 1 2 3
1 2 3 4 5
4
6
0 1 2 3
1 2 3 4 5
4
6
0 1 2 3
1 2 3 4 5
4
6
0 1 2 3
1 2 3 4 5
4
6
(a) (b) (c)
(d) (e)
(f) (g)
parity parity
interval
octagon
x+=z; x+=z z++; z++; y1=f(x) y2=x assert y1!= y2
T1
T2
T3
x+=z; x+=z z++; z++; y1=f(x) y2=x assert y1!= y2
T1
T2
T3
x+=z; x+=z z++; z++; y1=f(x) y2=x assert y1!= y2
T1
T2
T3
x+=z; x+=z z++; z++; y1=f(x) y2=x assert y1!= y2
T1
T2
T3
x+=z; x+=z z++; z++; y1=f(x) y2=x assert y1!= y2
T1
T2
T3
x+=z; x+=z z++; z++; y1=f(x) y2=x assert y1!= y2
T1
T2
T3
x+=z; x+=z z++; z++; y1=f(x) y2=x assert y1!= y2
T1
T2
T3
46
Multiple Solutions
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++])
Performance: smallest atomic sections
Minimal satisfying assignments 1 = [z++,z++] 2 = [x+=z,x+=z]
47
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
48
Program P
Abstract counter example
Abstraction Refinement
ϕ
Verify
Abstraction-Guided Synthesis
Program Restriction
Implement P’
Abstract counter example
49
Specification S
Abstraction
AGS instances Avoid Implementation
Mechanism Abstraction Space (examples)
Reference
Context switch Atomic sections Numerical abstractions [POPL’10]
Inter-thread ordering
Synchronization barriers
Numerical abstractions [SAS’13]
Intra-thread ordering
Memory fences Partial-Coherence abstractions for store buffers
[FMCAD’10] [PLDI’11] [PLDI’12]
Transition Conditional critical regions (CCRs)
Observability [TACAS’09]
…
50
Program P
specification S
Abstract counter example
Abstraction
Abstraction Refinement
Change the specification to match the abstraction
ϕ
Verify
General Setting Revisited
Program Restriction
Implement P’
Abstract counter example
S’ Spec
Weakening
Σ
51
Summary Synthesis of Concurrent Data Structures Search-based synthesis: schema + semantic search Discovered new algorithmic variants
Synthesis of Synchronization Input is a program, synthesizer repairs programs Instances: atomics, barriers, memory fences, etc…
Future Challenges Synthesis of “space” is key Apply techniques in symbolic or dynamic execution Combining synchronization primitives
52
Thank You
Questions ?
53