61
C. Flanagan 1 Types for Atomicity Cormac Flanagan UC Santa Cruz Stephen N. Freund Williams College Shaz Qadeer Microsoft Research Analysis of Concurrent Software Types for Atomicity

Analysis of Concurrent Software Types for Atomicity

  • Upload
    leif

  • View
    43

  • Download
    0

Embed Size (px)

DESCRIPTION

Analysis of Concurrent Software Types for Atomicity. Cormac Flanagan UC Santa Cruz. Stephen N. Freund Williams College Shaz Qadeer Microsoft Research. Race Conditions. class Ref { int i; void inc() { int t; t = i; i = t+1; } } Ref x = new Ref(0); parallel { - PowerPoint PPT Presentation

Citation preview

Page 1: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 1Types for Atomicity

Cormac FlanaganUC Santa Cruz

Stephen N. FreundWilliams College

Shaz QadeerMicrosoft Research

Analysis of Concurrent Software

Types for Atomicity

Page 2: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 2Types for Atomicity

Race Conditions

class Ref { int i; void inc() { int t; t = i; i = t+1; }} Ref x = new Ref(0);parallel { x.inc(); // two calls happen x.inc(); // in parallel}assert x.i == 2;

A race condition occurs if

• two threads access a shared variable at the same time

• at least one of those accesses is a write

Page 3: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 3Types for Atomicity

Lock-Based Synchronizationclass Ref { int i; // guarded by this void inc() { int t; synchronized (this) { t = i; i = t+1; } }} Ref x = new Ref(0);parallel { x.inc(); // two calls happen x.inc(); // in parallel}assert x.i == 2;

• Field guarded by a lock

• Lock acquired before accessing field

• Ensures race freedom

Page 4: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 4Types for Atomicity

Limitations of Race-Freedomclass Ref { int i; // guarded by this void inc() { int t; synchronized (this) { t = i; i = t+1; } }} Ref x = new Ref(0);parallel { x.inc(); // two calls happen x.inc(); // in parallel}assert x.i == 2;

Ref.inc()• race-free• behaves correctly in a

multithreaded context

Page 5: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 5Types for Atomicity

Limitations of Race-Freedom

class Ref { int i; void inc() { int t; synchronized (this) { t = i; } synchronized (this) { i = t+1; } } ...}

Ref.inc()• race-free• behaves incorrectly in a

multithreaded context

Race freedom does not prevent errors due to unexpected interactionsbetween threads

Page 6: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 6Types for Atomicity

Limitations of Race-Freedom

class Ref { int i; void inc() { int t; synchronized (this) { t = i; i = t+1; } } synchronized void read() { return i; } ...}

Page 7: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 7Types for Atomicity

Limitations of Race-Freedom

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

void read() { return i; } ...}

Ref.read() • has a race condition• behaves correctly in a

multithreaded context

Race freedom is not necessary to prevent errors due to unexpected interactionsbetween threads

Page 8: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 8Types for Atomicity

Race-Freedom

• Race-freedom is neither necessary nor sufficient to ensure the absence of errors due to unexpected interactions between threads

Page 9: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 9Types for Atomicity

Atomicity•The method inc() is atomic if concurrent

threads do not interfere with its behavior

•Guarantees that for every execution

•there is a serial execution with same behavior

acq(this) t=i i=t+1 rel(this)x y z

acq(this) t=i i=t+1 rel(this)x y z

acq(this) t=i i=t+1 rel(this)x y z

Page 10: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 10Types for Atomicity

Motivations for Atomicity

1. Stronger property than race freedom

Page 11: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 11Types for Atomicity

Motivations for Atomicity

1. Stronger property than race freedom

2. Enables sequential reasoning

Page 12: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 12Types for Atomicity

Sequential Program Execution

void inc() {

..

..

}

precond.

postcond.

inc()

Page 13: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 13Types for Atomicity

Multithreaded Execution

void inc() {

..

..

}

Page 14: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 14Types for Atomicity

Multithreaded Execution

void inc() {

..

..

}

Page 15: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 15Types for Atomicity

Multithreaded Execution

Atomicity• guarantees concurrent

threads do not interfere with atomic method

Page 16: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 16Types for Atomicity

Motivations for Atomicity

1. Stronger property than race freedom

2. Enables sequential reasoning3. Simple, powerful correctness

property

Page 17: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 17Types for Atomicity

Model Checking of Software Models

// filesystem.c

void create(..) { ...}void unlink(..) { ... }

// filesystem.c

void create(..) { ...}void unlink(..) { ... }

Specificationfor

filesystem.c

Specificationfor

filesystem.c

Model

Checker

filesystemmodel

filesystemmodel

ModelConstruction

Page 18: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 18Types for Atomicity

Model Checking of Software

// filesystem.c

void create(..) { ...}void unlink(..) { ... }

// filesystem.c

void create(..) { ...}void unlink(..) { ... }

Specificationfor

filesystem.c

Specificationfor

filesystem.c

Model

Checker

Page 19: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 19Types for Atomicity

Experience with Calvin Software Checker

// filesystem.c

void create(..) { ...}void unlink(..) { ... }

// filesystem.c

void create(..) { ...}void unlink(..) { ... }

Specificationfor

filesystem.c

Specificationfor

filesystem.c

expr

esse

d in

term

s of

concretestate

Calvin

theoremproving

x

Page 20: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 20Types for Atomicity

Experience with Calvin Software Checker

// filesystem.c

void create(..) { ...}void unlink(..) { ... }

// filesystem.c

void create(..) { ...}void unlink(..) { ... }

Specificationfor

filesystem.c

Specificationfor

filesystem.c

concretestate

Calvin

theoremproving

abstractstate

AbstractionInvariant

?x

Page 21: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 21Types for Atomicity

Experience with Calvin Software Checker

/*@ global_invariant (\forall int i; inodeLocks[i] == null ==> 0 <= inodeBlocknos[i] && inodeBlocknos[i] < Daisy.MAXBLOCK) */ //@ requires 0 <= inodenum && inodenum < Daisy.MAXINODE; //@ requires i != null //@ requires DaisyLock.inodeLocks[inodenum] == \tid //@ modifies i.blockno, i.size, i.used, i.inodenum //@ ensures i.blockno == inodeBlocknos[inodenum] //@ ensures i.size == inodeSizes[inodenum] //@ ensures i.used == inodeUsed[inodenum] //@ ensures i.inodenum == inodenum //@ ensures 0 <= i.blockno && i.blockno < Daisy.MAXBLOCK

static void readi(long inodenum, Inode i) {i.blockno = Petal.readLong(STARTINODEAREA + (inodenum * Daisy.INODESIZE));i.size = Petal.readLong(STARTINODEAREA + (inodenum * Daisy.INODESIZE) + 8);i.used = Petal.read(STARTINODEAREA + (inodenum * Daisy.INODESIZE) + 16) == 1;i.inodenum = inodenum;// read the right bytes, put in inode

}

Page 22: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 22Types for Atomicity

The Need for Atomicity

// filesystem.c

void create(..) { ...}void unlink(..) { ... }

// filesystem.c

void create(..) { ...}void unlink(..) { ... }

// filesystem.c

void create(..) { ...}void unlink(..) { ... }

// filesystem.c

void create(..) { ...}void unlink(..) { ... }

Sequential case:code inspection &testing mostly ok

Page 23: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 23Types for Atomicity

The Need for Atomicity

// filesystem.c

atomic void create(..) { ...}atomic void unlink(..) { ... }

// filesystem.c

atomic void create(..) { ...}atomic void unlink(..) { ... }

// filesystem.c

void create(..) { ...}void unlink(..) { ... }

// filesystem.c

void create(..) { ...}void unlink(..) { ... }

Sequential case:code inspection &testing ok

Atomicity

Checker

Page 24: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 24Types for Atomicity

Motivations for Atomicity

1. Stronger property than race freedom

2. Enables sequential reasoning3. Simple, powerful correctness

property

Page 25: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 25Types for Atomicity

Atomicity• Canonical property

– (cmp. serializability, linearizability, ...)

• Enables sequential reasoning– simplifies validation of multithreaded code

• Matches practice in existing code– most methods (80%+) are atomic– many interfaces described as “thread-safe”

• Can verify atomicity statically or dynamically– atomicity violations often indicate errors– leverages Lipton’s theory of reduction

Page 26: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 26Types for Atomicity

Reduction [Lipton 75]acq(this)

X t=i Y i=t+1 Z rel(this)

acq(this)

X t=iY i=t+1 Zrel(this)

acq(this) X t=iY i=t+1 Z rel(this)

acq(this)X t=iY i=t+1 Z rel(this)

Page 27: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 27Types for Atomicity

Movers•right-mover

– lock acquireS0 S1 S2

acq(this) x

S0 T1 S2

x acq(this)

Page 28: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 28Types for Atomicity

Movers•right-mover

– lock acquire

• left-mover– lock release

S7T6S5

rel(this) z

S7S6S5

rel(this)z

Page 29: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 29Types for Atomicity

Movers•right-mover

– lock acquire

•left-mover– lock acquire

•both-mover– race-free field access

S2 S3 S4

r=bal y

S2 T3 S4

r=baly

S2 T3 S4

r=bal x

S2 S3 S4

r=balx

Page 30: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 30Types for Atomicity

Movers•right-mover

– lock acquire

• left-mover– lock acquire

•both-mover– race-free field access

•non-mover (atomic)– access to "racy" fields

S2 S3 S4

r=bal y

S1

x

Page 31: Analysis of Concurrent Software Types for Atomicity

C. Flanagan Types for Atomicity 31

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

Code Classificationright: lock acquireleft: lock release(both) mover: race-free variable accessatomic: conflicting variable access

acq(this) j=bal bal=j+n rel(this)

right mover mover left

atomic

Page 32: Analysis of Concurrent Software Types for Atomicity

C. Flanagan Types for Atomicity 32

acq(this) bal=j+n rel(this)

right mover left right mover left

Composing Atomicities

atomic

acq(this) j=bal rel(this)

atomic

compound

void deposit(int n) { int j; synchronized(this) { j = bal; } synchronized(this) { bal = j + n; } }

Page 33: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 33Types for Atomicity

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 34: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 34Types for Atomicity

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 35: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 35Types for Atomicity

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 36: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 36Types for Atomicity

Conditional Atomicity Details

• In conditional atomicity (x?b1:b2), x must be a lock expression (ie, constant)

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

Page 37: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 37Types for Atomicity

java.lang.StringBuffer/** ... used by the compiler to implement the binary

string concatenation operator ... String buffers are safe for use by multiple

threads. The methods are synchronized so that all the operations on any particular instance behave as if they occur in some serial order that is consistent with the order of the method calls made by each of the individual threads involved.

*/public atomic class StringBuffer { ... }

FALSE

Page 38: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 38Types for Atomicity

java.lang.StringBuffer is not Atomic!

public atomic StringBuffer { private int count guarded_by this; public synchronized int length() { return count; } public synchronized void getChars(...) { ... }

public synchronized void append(StringBuffer sb){

int len = sb.length(); ... ... sb.getChars(...,len,...); ... }}

AA

CA

A

sb.length() acquires the lock on sb, gets the length, and releases lock

use of stale len may yield StringIndexOutOfBoundsExceptioninside getChars(...)

other threads can change sb

append(...) is not atomic

Page 39: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 39Types for Atomicity

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 40: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 40Types for Atomicity

Atomicity Inference

Page 41: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 41Types for Atomicity

UnannotatedJava

Program

atomicityinference

Rcc/Sat

AtomicityWarnings

Program withAtomicity

Annotations

Bohr

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

Bohr

Page 42: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 42Types for Atomicity

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 43: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 43Types for Atomicity

Atomicity Details• Partial order of atomicities

const

error

compound

atomic

mover

x?mover:atomic

Page 44: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 44Types for Atomicity

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 45: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 45Types for Atomicity

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 46: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 46Types for Atomicity

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 47: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 47Types for Atomicity

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 48: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 48Types for Atomicity

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,a): atomicity of synchronized(l) { e } where e has atomicity a

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 49: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 49Types for Atomicity

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 50: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 50Types for Atomicity

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 51: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 51Types for Atomicity

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 52: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 52Types for Atomicity

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 53: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 53Types for Atomicity

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 54: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 54Types for Atomicity

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 55: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 55Types for Atomicity

3. Compute Least Fixed Point

• Initial assignment A: 1 = 2 = const

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

– set A() to A() ㄩ A(s)– repeat until quiescence

Page 56: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 56Types for Atomicity

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 57: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 57Types for Atomicity

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 58: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 58Types for Atomicity

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 59: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 59Types for Atomicity

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 60: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 60Types for Atomicity

Related Work• Reduction

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

– other applications: • 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]

Page 61: Analysis of Concurrent Software Types for Atomicity

C. Flanagan 61Types for Atomicity

Conclusions And Future Directions• Atomicity a fundamental concept

– improves over race freedom– matches programmer intuition and practice – simplifies reasoning about correctness– enables concise and trustable documentation

• Many approaches for verifying atomicity– static type systems – dynamic checking (tomorrow)– ... hybrid checkers ...– ... model checkers ...