c. flanaganatomicity for reliable concurrent software - pldi'05 tutorial1 atomicity for...

68
C. Flanagan Atomicity for Reliable Concurrent Software - PLDI'05 Tutoria l 1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and Atomicity

Post on 19-Dec-2015

218 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial 1

Atomicity for ReliableConcurrent Software

Part 3a:Types for Race-Freedom

and Atomicity

Page 2: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 2Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

Verifying Race Freedom with Types

class Ref { int i; void add(Ref r) { i = i + r.i; }} Ref x = new Ref(0);Ref y = new Ref(3);parallel { synchronized (x,y) { x.add(y); } synchronized (x,y) { x.add(y); }}assert x.i == 6;

Page 3: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 3Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

Verifying Race Freedom with Types

class Ref { int i guarded_by this; void add(Ref r) requires this, r { i = i + r.i; }} Ref x = new Ref(0);Ref y = new Ref(3);parallel { synchronized (x,y) { x.add(y); } synchronized (x,y) { x.add(y); }}assert x.i == 6;

check: this { this, r }

Page 4: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 4Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

Verifying Race Freedom with Types

class Ref { int i guarded_by this; void add(Ref r) requires this, r { i = i + r.i; }} Ref x = new Ref(0);Ref y = new Ref(3);parallel { synchronized (x,y) { x.add(y); } synchronized (x,y) { x.add(y); }}assert x.i == 6;

check: this { this, r } check: this[this:=r] = r { this, r }

replace this by r

Page 5: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 5Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

Verifying Race Freedom with Types

class Ref { int i guarded_by this; void add(Ref r) requires this, r { i = i + r.i; }} Ref x = new Ref(0);Ref y = new Ref(3);parallel { synchronized (x,y) { x.add(y); } synchronized (x,y) { x.add(y); }}assert x.i == 6;

check: this { this, r } check: this[this:=r] = r { this, r }

check: {this,r}[this:=x,r:=y] { x, y }

replace formals this,rby actuals x,y

Page 6: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 6Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

Verifying Race Freedom with Types

class Ref { int i guarded_by this; void add(Ref r) requires this, r { i = i + r.i; }} Ref x = new Ref(0);Ref y = new Ref(3);parallel { synchronized (x,y) { x.add(y); } synchronized (x,y) { x.add(y); }}assert x.i == 6;

check: {this,r}[this:=x,r:=y] { x, y }

check: this { this, r } check: this[this:=r] = r { this, r }

check: {this,r}[this:=x,r:=y] { x, y }

Soundness Theorem:Well-typed programs are race-free

replace formals this,rby actuals x,y

Page 7: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 7Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

Basic Type Inference

class Ref { int i; void add(Ref r) { i = i + r.i; }} Ref x = new Ref(0);Ref y = new Ref(3);parallel { synchronized (x,y) { x.add(y); } synchronized (x,y) { x.add(y); }}assert x.i == 6;

Page 8: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 8Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

Basic Type Inferencestatic final Object m =new Object();

class Ref { int i; void add(Ref r) { i = i + r.i; }} Ref x = new Ref(0);Ref y = new Ref(3);parallel { synchronized (x,y) { x.add(y); } synchronized (x,y) { x.add(y); }}assert x.i == 6;

Iterative GFP algorithm:• [Flanagan-Freund,

PASTE’01]

• Start with maximum set of annotations

Page 9: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 9Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

Basic Type Inferencestatic final Object m =new Object();

class Ref { int i guarded_by this, m; void add(Ref r) { i = i + r.i; }} Ref x = new Ref(0);Ref y = new Ref(3);parallel { synchronized (x,y) { x.add(y); } synchronized (x,y) { x.add(y); }}assert x.i == 6;

Iterative GFP algorithm:• [Flanagan-Freund,

PASTE’01]

• Start with maximum set of annotations

Page 10: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 10Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

Basic Type Inferencestatic final Object m =new Object();

class Ref { int i guarded_by this, m; void add(Ref r) requires this, r, m { i = i + r.i; }} Ref x = new Ref(0);Ref y = new Ref(3);parallel { synchronized (x,y) { x.add(y); } synchronized (x,y) { x.add(y); }}assert x.i == 6;

Iterative GFP algorithm:• [Flanagan-Freund,

PASTE’01]

• Start with maximum set of annotations

Page 11: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 11Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

Basic Type Inferencestatic final Object m =new Object();

class Ref { int i guarded_by this, m; void add(Ref r) requires this, r, m { i = i + r.i; }} Ref x = new Ref(0);Ref y = new Ref(3);parallel { synchronized (x,y) { x.add(y); } synchronized (x,y) { x.add(y); }}assert x.i == 6;

XX

Iterative GFP algorithm:• [Flanagan-Freund,

PASTE’01]

• Start with maximum set of annotations

• Iteratively remove all incorrect annotations

Page 12: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 12Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

Basic Type Inferencestatic final Object m =new Object();

class Ref { int i guarded_by this, m; void add(Ref r) requires this, r, m { i = i + r.i; }} Ref x = new Ref(0);Ref y = new Ref(3);parallel { synchronized (x,y) { x.add(y); } synchronized (x,y) { x.add(y); }}assert x.i == 6;

XX

Iterative GFP algorithm:• [Flanagan-Freund, PASTE’01]

• Start with maximum set of annotations

• Iteratively remove all incorrect annotations

• Check each field still has a protecting lock

Sound, complete, fast

But type system too basic

Page 13: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 13Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

Harder Example: External Locking

class Ref { int i; void add(Ref r) { i = i + r.i; }} Object m = new Object();Ref x = new Ref(0);Ref y = new Ref(3);parallel { synchronized (m) { x.add(y); } synchronized (m) { x.add(y); }}assert x.i == 6;

• Field i of x and y protected by external lock m

• Not typable with basic type system– m not in scope at i

• Requires more expressive type system with ghost parameters

Page 14: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 14Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

Ghost Parameters on Classes

class Ref { int i; void add(Ref r) { i = i + r.i; }} Object m = new Object();Ref x = new Ref(0);Ref y = new Ref(3);parallel { synchronized (m) { x.add(y); } synchronized (m) { x.add(y); }}assert x.i == 6;

Page 15: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 15Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

Ghost Parameters on Classes

class Ref<ghost g> { int i; void add(Ref r) { i = i + r.i; }} Object m = new Object();Ref x = new Ref(0);Ref y = new Ref(3);parallel { synchronized (m) { x.add(y); } synchronized (m) { x.add(y); }}assert x.i == 6;

• Ref parameterized by external ghost lock g

Page 16: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 16Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

Ghost Parameters on Classes

class Ref<ghost g> { int i guarded_by g; void add(Ref r) { i = i + r.i; }} Object m = new Object();Ref x = new Ref(0);Ref y = new Ref(3);parallel { synchronized (m) { x.add(y); } synchronized (m) { x.add(y); }}assert x.i == 6;

• Ref parameterized by external ghost lock g

• Field i guarded by g

Page 17: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 17Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

Ghost Parameters on Classes

class Ref<ghost g> { int i guarded_by g; void add(Ref r) requires g { i = i + r.i; }} Object m = new Object();Ref x = new Ref(0);Ref y = new Ref(3);parallel { synchronized (m) { x.add(y); } synchronized (m) { x.add(y); }}assert x.i == 6;

• Ref parameterized by external ghost lock g

• Field i guarded by g• g held when add

called

Page 18: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 18Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

Ghost Parameters on Classes

class Ref<ghost g> { int i guarded_by g; void add(Ref<g> r) requires g { i = i + r.i; }} Object m = new Object();Ref x = new Ref(0);Ref y = new Ref(3);parallel { synchronized (m) { x.add(y); } synchronized (m) { x.add(y); }}assert x.i == 6;

• Ref parameterized by external ghost lock g

• Field i guarded by g• g held when add

called• Argument r also

parameterized by g

Page 19: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 19Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

Ghost Parameters on Classes

class Ref<ghost g> { int i guarded_by g; void add(Ref<g> r) requires g { i = i + r.i; }} Object m = new Object();Ref<m> x = new Ref<m>(0);Ref<m> y = new Ref<m>(3);parallel { synchronized (m) { x.add(y); } synchronized (m) { x.add(y); }}assert x.i == 6;

• Ref parameterized by external ghost lock g

• Field i guarded by g• g held when add

called• Argument r also

parameterized by g

• x and y parameterized by lock m

Page 20: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 20Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

Type Checking Ghost Parameters

class Ref<ghost g> { int i guarded_by g; void add(Ref<g> r) requires g { i = i + r.i; }} Object m = new Object();Ref<m> x = new Ref<m>(0);Ref<m> y = new Ref<m>(3);parallel { synchronized (m) { x.add(y); } synchronized (m) { x.add(y); }}assert x.i == 6;

check: {g} [this:=x,r:=y, g:=m] {m}

Page 21: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 21Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

Type Inference with Ghosts• HARD

– iterative GFP algorithm does not work– check may fail because of two annotations

• which should we remove?

– requires backtracking search

Page 22: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 22Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

Type Inference With GhostsType

Inference

class A { int f; }class B<ghost y> ...A a = ...;

class A<ghost g>{ int f guarded_by g;}class B<ghost y>...A<m> a = ...;

Page 23: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 23Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

Boolean Satisfiability

(t1 t2 t3) (t2 t1 t4) (t2 t3 t4)

SATSolver

t1 = truet2 = falset3 = truet4 = true

Page 24: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 24Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

class A<ghost x,y,z> ... class B ...class C ...A a = ...B b = ...C c = ...

Reducing SAT to Type Inference

TypeInference

class A<ghost x,y,z>... class B<ghost x,y,z>...class C<ghost x,y,z>...A<p1,p2,p3> a = ...B<p1,n1,n4> b = ...C<p2,n3,p4> c = ...

(t1 t2 t3) (t2 t1 t4) (t2 t3 t4)

Construct Program From

Formula

SATSolver

t1 = truet2 = falset3 = truet4 = true

Construct Assignment From

Annotations

Page 25: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 25Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

Restricted CasesO(2n)

...

O(n3)

O(n2)

O(n log n)

O(n)

O(1)

# Params:

3

2

1

0

???

Page 26: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 26Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

Rcc/Sat Type Inference Tool

(t1 t2 t3) (t2 t1 t4) (t2 t3 t4)

Construct Formula From

Program

SATSolver

t1 = truet2 = falset3 = truet4 = true

Construct Annotations From Assignment

class A { int f; ..}...A a = ...;

class A<ghost g>{ int f guarded_by g; ..}...A<m> a = ...;

Page 27: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 27Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

Reducing Type Inference to SAT

class Ref {

int i;

void add(Ref r)

{

i = i

+ r.i;

}

}

Page 28: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 28Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

Reducing Type Inference to SAT

class Ref<ghost g1,g2,...,gn> {

int i;

void add(Ref r)

{

i = i

+ r.i;

}

}

Page 29: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 29Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

Reducing Type Inference to SAT

class Ref<ghost g> {

int i;

void add(Ref r)

{

i = i

+ r.i;

}

}

• Add ghost parameters <ghost g> to each class declaration

Page 30: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 30Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

Reducing Type Inference to SAT

class Ref<ghost g> {

int i guarded_by 1;

void add(Ref r)

{

i = i

+ r.i;

}

}

• Add ghost parameters <ghost g> to each class declaration

• Add guarded_by i to each field declaration– type inference resolves

i to some lock

Page 31: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 31Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

Reducing Type Inference to SAT

class Ref<ghost g> {

int i guarded_by 1;

void add(Ref<2> r)

{

i = i

+ r.i;

}

}

• Add ghost parameters <ghost g> to each class declaration

• Add guarded_by i to each field declaration– type inference resolves

i to some lock

• Add <2> to each class reference

Page 32: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 32Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

Reducing Type Inference to SAT

class Ref<ghost g> {

int i guarded_by 1;

void add(Ref<2> r)

requires {

i = i

+ r.i;

}

}

• Add ghost parameters <ghost g> to each class declaration

• Add guarded_by i to each field declaration– type inference resolves

i to some lock

• Add <2> to each class reference

• Add requires i to each method– type inference resolves

i to some set of locks

Page 33: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 33Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

Reducing Type Inference to SAT

class Ref<ghost g> {

int i guarded_by 1;

void add(Ref<2> r)

requires {

i = i

+ r.i;

}

}

Constraints:1 { this, g }

2 { this, g }

{ this, g, r }

1 1[this := r, g:= 2]

Page 34: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 34Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

Constraints:1 { this, g }

2 { this, g }

{ this, g, r }

1 1[this := r, g:= 2]

Reducing Type Inference to SAT

Encoding:

1 = (b1 ? this : g )

2 = (b2 ? this : g )

= { b3 ? this, b4 ? g, b5 ?

r }

class Ref<ghost g> {

int i guarded_by 1;

void add(Ref<2> r)

requires {

i = i

+ r.i;

}

}

Use boolean variablesb1,...,b5 to encode choices for 1, 2,

Page 35: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 35Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

Constraints:1 { this, g }

2 { this, g }

{ this, g, r }

1 1[this := r, g:= 2]

Reducing Type Inference to SAT

class Ref<ghost g> {

int i guarded_by 1;

void add(Ref<2> r)

requires {

i = i

+ r.i;

}

}

1[this := r, g:= 2]

Use boolean variablesb1,...,b5 to encode choices for 1, 2,

Encoding:

1 = (b1 ? this : g )

2 = (b2 ? this : g )

= { b3 ? this, b4 ? g, b5 ?

r }

Page 36: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 36Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

Constraints:1 { this, g }

2 { this, g }

{ this, g, r }

1 1[this := r, g:= 2]

Reducing Type Inference to SAT

class Ref<ghost g> {

int i guarded_by 1;

void add(Ref<2> r)

requires {

i = i

+ r.i;

}

}

1[this := r, g:= 2]

(b1 ? this : g ) [this := r, g:= 2]

Use boolean variablesb1,...,b5 to encode choices for 1, 2,

Encoding:

1 = (b1 ? this : g )

2 = (b2 ? this : g )

= { b3 ? this, b4 ? g, b5 ?

r }

Page 37: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 37Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

Constraints:1 { this, g }

2 { this, g }

{ this, g, r }

1 1[this := r, g:= 2]

Reducing Type Inference to SAT

class Ref<ghost g> {

int i guarded_by 1;

void add(Ref<2> r)

requires {

i = i

+ r.i;

}

}

1[this := r, g:= 2]

(b1 ? this : g ) [this := r, g:= 2]

(b1 ? r : 2)

Use boolean variablesb1,...,b5 to encode choices for 1, 2,

Encoding:

1 = (b1 ? this : g )

2 = (b2 ? this : g )

= { b3 ? this, b4 ? g, b5 ?

r }

Page 38: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 38Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

Constraints:1 { this, g }

2 { this, g }

{ this, g, r }

1 1[this := r, g:= 2]

Reducing Type Inference to SAT

class Ref<ghost g> {

int i guarded_by 1;

void add(Ref<2> r)

requires {

i = i

+ r.i;

}

}

1[this := r, g:= 2]

(b1 ? this : g ) [this := r, g:= 2]

(b1 ? r : 2)

(b1 ? r : (b2 ? this : g )) { b3 ? this, b4 ? g, b5 ?

r }

Use boolean variablesb1,...,b5 to encode choices for 1, 2,

Encoding:

1 = (b1 ? this : g )

2 = (b2 ? this : g )

= { b3 ? this, b4 ? g, b5 ?

r }

Page 39: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 39Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

Constraints:1 { this, g }

2 { this, g }

{ this, g, r }

1 1[this := r, g:= 2]

Reducing Type Inference to SAT

class Ref<ghost g> {

int i guarded_by 1;

void add(Ref<2> r)

requires {

i = i

+ r.i;

}

}

1[this := r, g:= 2]

(b1 ? this : g ) [this := r, g:= 2]

(b1 ? r : 2)

(b1 ? r : (b2 ? this : g )) { b3 ? this, b4 ? g, b5 ?

r }

Use boolean variablesb1,...,b5 to encode choices for 1, 2,

Encoding:

1 = (b1 ? this : g )

2 = (b2 ? this : g )

= { b3 ? this, b4 ? g, b5 ?

r }

Clauses:

(b1 b5) (b1 b2 b3)(b1 b2 b4)

Page 40: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 40Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

Overview of Type Inference

SAT soln:

b1=false...

ConstraintSolution:1 = g

...

SAT problem:

(b1 b5) ...

Constraints:

1 { this, g }

...

Add Unknowns:class Ref<ghost g> { int i guarded_by 1 ; ...

Annotated Program:class Ref<ghost g> { int i guarded_by g; ...

Unannotated Program:class Ref { int i; ...

b1,... encodes choice for 1,...

ChaffSAT solver

Error: potential race on field i

unsatisfiable

satisfiable

Page 41: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial 41

Part 3a:

Types for Atomicity

Page 42: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 42Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

Checking Atomicity

atomic void inc() { int t; synchronized (this) { t = i; i = t + 1; } }

R: right-mover lock acquireL: left-mover lock releaseB: both-mover race-free variable

accessA: atomic conflicting variable

access

Reducible blocks have form: (R|B)* [A] (L|B)*

composition rules: right ; mover = right right ; left = atomic atomic ; atomic = cmpd

Page 43: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 43Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

Checking Atomicity (cont.)

atomic void inc() { int t; synchronized (this) { t = i; } synchronized (this) { i = t + 1; }}

R: right-mover lock acquireL: left-mover lock releaseB: both-mover race-free variable

accessA: atomic conflicting variable

access

R B L R B L

acq(this)t=i i=t+1 rel(this)acq(this) rel(this)

Compound

AA

Page 44: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 44Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

java.lang.Vectorinterface Collection { atomic int length(); atomic void toArray(Object a[]);}

class Vector { int count; Object data[];

atomic Vector(Collection c) { count = c.length(); atomic data = new Object[count]; mover ... c.toArray(data); atomic }}

compound

X

Page 45: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 45Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

Conditional Atomicity

atomic void deposit(int n) { synchronized(this) { right int j = bal; mover bal = j + n; mover } left}

atomic void depositTwice(int n) { synchronized(this) { deposit(n); atomic deposit(n); atomic }}

X

atomic

Page 46: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 46Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

Conditional Atomicity

atomic void deposit(int n) { synchronized(this) { right mover int j = bal; mover mover bal = j + n; mover mover } left mover}

atomic void depositTwice(int n) { synchronized(this) { deposit(n); atomic deposit(n); atomic }}

if this already held

atomic mover

Page 47: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 47Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

Conditional Atomicity

(this ? mover : atomic) void deposit(int n) { synchronized(this) { right mover int j = bal; mover mover bal = j + n; mover mover } left mover}

atomic void depositTwice(int n) { synchronized(this) { deposit(n); (this ? mover : atomic) deposit(n); (this ? mover : atomic) }}

Page 48: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 48Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

Conditional Atomicity Details

• In conditional atomicity (x?b1:b2), x must be a const (aka final) expression

(x ? mover : compound) void m() {...}

atomic void mutate() { synchronized(x) { x = y; m(); // is m() a mover??? }}

• Composition rules a ; (x?b1:b2) = x ? (a;b1) : (a;b2)

Page 49: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 49Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

UnannotatedJava

Program

atomicityinference

Rcc/Sat

AtomicityWarnings

Program withAtomicity

Annotations

Bohr

• Type inference for atomicity– finds smallest atomicity for each method

Bohr

Page 50: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 50Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

Atomicity Inferenceclass A<ghost x> { int f guarded_by this; int g guarded_by x; void m() {...}}

AtomicityConstraints

ConstraintsSolution

ConstraintSolver

class A<ghost x> { int f guarded_by this; int g guarded_by x; atomic void m() {...}}

Program w/ Locking Annotations

Program w/ Atomicity Annotations

Page 51: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 51Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

class Account { int bal guarded_by this; 1 void deposit(int n) { synchronized(this) { int j = this.bal; j = this.bal + n; } }}

class Bank {

2 void double(final Account c) { synchronized(c) { int x = c.bal; c.deposit(x); } }}

1.Add atomicityvariables

Page 52: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 52Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

class Account { int bal guarded_by this; 1 void deposit(int n) { synchronized(this) { int j = this.bal; j = this.bal + n; } }}

class Bank {

2 void double(final Account c) { synchronized(c) { int x = c.bal; c.deposit(x); } }}

2. Generate constraints over atomicity variables

s ≤ i

3. Find assignment A

Atomicity expression s ::= const | mover | atomic | cmpd | error |

| s1 ; s2

| x ? s1 : s2

| S(l, s) | WFA(E, s)

Page 53: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 53Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

class Account { int bal guarded_by this; 1 void deposit(int n) { synchronized(this) { int j = this.bal; j = this.bal + n; } }}

class Bank {

2 void double(final Account c) { synchronized(c) { int x = c.bal; c.deposit(x); } }}

S(this, ((const; this?mover:error); (const;this?mover:error)))

Page 54: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 54Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

class Account { int bal guarded_by this; 1 void deposit(int n) { synchronized(this) { int j = this.bal; j = this.bal + n; } }}

class Bank {

2 void double(final Account c) { synchronized(c) { int x = c.bal; c.deposit(x); } }}

S(this, ((const; this?mover:error); (const; this?mover:error)))

Page 55: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 55Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

class Account { int bal guarded_by this; 1 void deposit(int n) { synchronized(this) { int j = this.bal; j = this.bal + n; } }}

class Bank { final Account c;

2 void double() { synchronized(this.c) { int x = this.c.bal; this.c.deposit(x); } }}

S(this, ((const; this?mover:error); (const; this?mover:error)))

S(l,b): atomicity of synchronized(l) { e } where e has atomicity b

S(l, mover) = l ? mover : atomic S(l, atomic) = atomic S(l, compound) = compound S(l, l?b1:b2) = S(l,b1)

S(l, m?b1:b2) = m ? S(l,b1) : S(l,b2) if l m

Page 56: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 56Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

class Account { int bal guarded_by this; 1 void deposit(int n) { synchronized(this) { int j = this.bal; j = this.bal + n; } }}

class Bank {

2 void double(final Account c) { synchronized(c) { int x = c.bal; c.deposit(x); } }}

S(this, ((const; this?mover:error); (const; this?mover:error)))

≤ 1

Page 57: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 57Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

class Account { int bal guarded_by this; 1 void deposit(int n) { synchronized(this) { int j = this.bal; j = this.bal + n; } }}

class Bank {

2 void double(final Account c) { synchronized(c) { int x = c.bal; c.deposit(x); } }}

S(this, ((const; this?mover:error); (const; this?mover:error)))

≤ 1

(const; (this?mover:error)[this:=c]) (const;WFA(E, 1[this := this.a]))))

replace this withname of receiver

Page 58: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 58Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

class Account { int bal guarded_by this; 1 void deposit(int n) { synchronized(this) { int j = this.bal; j = this.bal + n; } }}

class Bank {

2 void double(final Account c) { synchronized(c) { int x = c.bal; c.deposit(x); } }}

S(this, ((const; this?mover:error); (const; this?mover:error)))

≤ 1

S(a, ((const; c?mover:error); (const; 1[this := c]))

≤ 2 DelayedSubstitution

Page 59: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 59Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

class Account { int bal guarded_by this; 1 void deposit(int n) { synchronized(this) { int j = this.bal; j = this.bal + n; } }}

class Bank {

2 void double(final Account c) { synchronized(c) { int x = c.bal; c.deposit(x); } }}

S(this, ((const; this?mover:error); (const; this?mover:error)))

≤ 1

S(c, ((const; c?mover:error); (const; 1[this := c])))

≤ 2

Page 60: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 60Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

Delayed Substitutions• Given [x := e]

– suppose becomes (x?mover:atomic) and e does not have const atomicity

– then (e?mover:atomic) is not valid

• WFA(E, b) = smallest atomicity b' where– b ≤ b'– b' is well-typed and constant in E

• WFA(E, (e?mover:atomic)) = atomic

Page 61: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 61Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

class Account { int bal guarded_by this; 1 void deposit(int n) { synchronized(this) { int j = this.bal; j = this.bal + n; } }}

class Bank {

2 void double(final Account c) { synchronized(c) { int x = c.bal; c.deposit(x); } }}

S(this, ((const; this?mover:error); (const; this?mover:error)))

≤ 1

S(c, ((const; c?mover:error); (const; WFA(E, 1[this:=c]))))

≤ 2

Page 62: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 62Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

3. Compute Least Fixed Point

• Initial assignment A: 1 = 2 = const

• Algorithm: – pick constraint s ≤ such that A(s) ≤ A()

– set A = A[ := A() ㄩ A(s)]– repeat until quiescence

Page 63: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 63Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

class Account { int bal guarded_by this; (this ? mover : atomic) void deposit(int n) { synchronized(this) { int j = this.bal; j = this.bal + n; } }}

class Bank {

(c ? mover : atomic) void double(final Account c) { synchronized(c) { int x = c.bal; c.deposit(x); } }}

Page 64: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 64Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

Validation

Program

Size

(KLOC) Time (s)

Time

(s/KLOC)

elevator 0.5 0.6 1.1tsp 0.7 1.4 2.0sor 0.7 0.8 1.2raytracer 2.0 1.7 0.9moldyn 1.4 4.9 3.5montecarlo 3.7 1.5 0.4mtrt 11.3 7.8 0.7jbb 30.5 11.2 0.4

(excludes Rcc/Sat time)

Page 65: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 65Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

Inferred Atomicities

0

20

40

60

80

100

elevator tsp sor ray-tracer moldyn monte-carlo

mtrt jbb

Program

% A

tom

ic

Methods Synch. Blocks

Page 66: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 66Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

Thread-Safe Classes

0

20

40

60

80

100

String

String

Buffe

r

Vecto

r

Infla

ter

Deflat

er

ZipFile

Obs

erva

ble

Synch

List

URL

PrintW

riter

Synch

Bool

Synch

Doubl

e

Class

% A

tom

ic

Methods Synch. Blocks

Page 67: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 67Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

Summary• Type inference for rccjava is NP-complete

– ghost parameters require backtracking search

• Reduce type inference to SAT– adequately fast up to 30,000 LOC– precise: 92-100% of fields verified race free

• Type checker and inference for atomicity– leverages information about race conditions– over 80% of methods in jbb are atomic

Page 68: C. FlanaganAtomicity for Reliable Concurrent Software - PLDI'05 Tutorial1 Atomicity for Reliable Concurrent Software Part 3a: Types for Race-Freedom and

C. Flanagan 68Atomicity for Reliable Concurrent Software - PLDI'05 Tutorial

Related Work• Reduction

– [Lipton 75, Lamport-Schneider 89, ...]

– other applications: • type systems [Flanagan-Qadeer 03, Flanagan-Freund-Qadeer 04]

• model checking [Stoller-Cohen 03, Flanagan-Qadeer 03]

• dynamic analysis [Flanagan-Freund 04, Wang-Stoller 04]

• Atomicity inference– type and effect inference [Talpin-Jouvelot 92,...]– dependent types [Cardelli 88]– ownership, dynamic [Sastakur-Agarwal-Stoller 04]