Synthesis for Concurrency · The Good • New algorithm • Fine-grained synchronization (CAS) The...

Preview:

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

Recommended