Types for Atomicity in Multithreaded Software Shaz Qadeer Microsoft Research (Joint work with Cormac...

36
Types for Atomicity in Multithreaded Software Shaz Qadeer Microsoft Research (Joint work with Cormac Flanagan)

Transcript of Types for Atomicity in Multithreaded Software Shaz Qadeer Microsoft Research (Joint work with Cormac...

Page 1: Types for Atomicity in Multithreaded Software Shaz Qadeer Microsoft Research (Joint work with Cormac Flanagan)

Types for Atomicity in Multithreaded Software

Shaz QadeerMicrosoft Research

(Joint work with Cormac Flanagan)

Page 2: Types for Atomicity in Multithreaded Software Shaz Qadeer Microsoft Research (Joint work with Cormac Flanagan)

Multithreaded Programs

•Operating systems• Databases, web servers, browsers, GUIs, ...

•Modern languages: Java, C#

Processor 1

Processor 2

Thread 1

Thread 2

Thread 3

Thread 4

Page 3: Types for Atomicity in Multithreaded Software Shaz Qadeer Microsoft Research (Joint work with Cormac Flanagan)

Reliable Multithreaded Software ?

•Correctness Problem– does program behaves correctly for all

inputs and all interleavings?– very hard to ensure with testing

•Bugs due to concurrency are insidious – non-deterministic, timing dependent– data corruption, crashes– difficult to detect, reproduce, eliminate

•Linux 2.4 log has 36 synchronization bug fixes

Page 4: Types for Atomicity in Multithreaded Software Shaz Qadeer Microsoft Research (Joint work with Cormac Flanagan)

Multithreaded Program Execution

Thread 1 ... int t1 = hits; hits = t1 + 1 ...

t2=hits hits=t2+1t1=hits hits=t1+1

hits=0 hits=2

t2=hits hits=t2+1t1=hits hits=t1+1

hits=0 hits=1

t2=hits hits=t2+1t1=hits hits=t1+1

hits=0 hits=1

Thread 2 ... int t2 = hits; hits = t2 + 1 ...

Page 5: Types for Atomicity in Multithreaded Software Shaz Qadeer Microsoft Research (Joint work with Cormac Flanagan)

Race Conditions

A race condition occurs if two threads access a shared variable at the same time, and at least one of the accesses is a writeThread 1 ... int t1 = hits; hits = t1 + 1 ...

Thread 2 ... int t2 = hits; hits = t2 + 1 ...

Page 6: Types for Atomicity in Multithreaded Software Shaz Qadeer Microsoft Research (Joint work with Cormac Flanagan)

Preventing Race ConditionsUsing Locks

•Lock can be held by at most one thread•Race conditions are prevented using locks– associate a lock with each shared variable– acquire lock before accessing variableThread 1

synchronized(lock) { int t1 = hits; hits = t1 + 1}

Thread 2 synchronized(lock) { int t2 = hits; hits = t2 + 1}

hits=0 hits=2

acq t1=hits hits=t1+1 rel acq t2=hits hits=t2+2 rel

Page 7: Types for Atomicity in Multithreaded Software Shaz Qadeer Microsoft Research (Joint work with Cormac Flanagan)

Race detection

• Static:– Sterling 93, Aiken-Gay 98, Flanagan-

Abadi 99, Flanagan-Freund 00, Boyapati-Rinard 01, von Praun-Gross 01, Boyapati-Lee-Rinard 02, Grossman 03

• Dynamic: – Eraser (Savage et al. 97)– Choi et al. 02

Page 8: Types for Atomicity in Multithreaded Software Shaz Qadeer Microsoft Research (Joint work with Cormac Flanagan)

int balance;

Race-free bank account

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

Page 9: Types for Atomicity in Multithreaded Software Shaz Qadeer Microsoft Research (Joint work with Cormac Flanagan)

int balance;

Bank account

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

int read( ) { int r; synchronized (this) { r = balance; } return r;}

void withdraw(int n) { int r = read( ); synchronized (this) { balance = r – n; }}

Race-freedom not sufficient!

Thread 1

deposit(10);

Thread 2

withdraw(10);

balance = 10

Page 10: Types for Atomicity in Multithreaded Software Shaz Qadeer Microsoft Research (Joint work with Cormac Flanagan)

int balance;

Atomic bank account (I)

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

int read( ) { int r; synchronized (this) { r = balance; } return r;}

void withdraw(int n) { synchronized (this) { balance = balance – n; }}

Page 11: Types for Atomicity in Multithreaded Software Shaz Qadeer Microsoft Research (Joint work with Cormac Flanagan)

java.lang.StringBuffer (jdk 1.4)

“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.”

Page 12: Types for Atomicity in Multithreaded Software Shaz Qadeer Microsoft Research (Joint work with Cormac Flanagan)

java.lang.StringBuffer is buggy!

public final class StringBuffer { private int count; private char[ ] value; . . public synchronized StringBuffer append (StringBuffer sb) { if (sb == null) sb = NULL; int len = sb.length( ); int newcount = count + len; if (newcount > value.length) expandCapacity(newcount); sb.getChars(0, len, value, count); // use of stale len count = newcount; return this; }

public synchronized int length( ) { return count; }

public synchronized void getChars(. . .) { . . . }}

Page 13: Types for Atomicity in Multithreaded Software Shaz Qadeer Microsoft Research (Joint work with Cormac Flanagan)

int balance;

Atomic bank account (II)

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

int read( ) { return balance;}

void withdraw(int n) { synchronized (this) { balance = balance – n; }}

Race-freedom not necessary!

Page 14: Types for Atomicity in Multithreaded Software Shaz Qadeer Microsoft Research (Joint work with Cormac Flanagan)

Race-Freedom

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

•Is there a more fundamental semantic correctness property?

Page 15: Types for Atomicity in Multithreaded Software Shaz Qadeer Microsoft Research (Joint work with Cormac Flanagan)

Atomicity•A method is atomic if it seems to execute “in

one step” even in presence of concurrently executing threads

•Common concept– “(strict) serializability” in databases– “linearizability” in concurrent objects– “thread-safe” multithreaded libraries

• “String buffers are safe for use by multiple threads. …”

•Fundamental semantic correctness property

Page 16: Types for Atomicity in Multithreaded Software Shaz Qadeer Microsoft Research (Joint work with Cormac Flanagan)

Definition of Atomicity

•deposit is atomic if for every interleaved execution, there is a non-interleaved execution with the same behavior

acq(this) r=bal bal=r+n rel(this)x y z

acq(this) r=bal bal=r+n rel(this)x y z

acq(this) r=bal bal=r+n rel(this)x y z

Non-interleaved execution of deposit

Interleaved executions of deposit

Page 17: Types for Atomicity in Multithreaded Software Shaz Qadeer Microsoft Research (Joint work with Cormac Flanagan)

blue thread holds lock red thread does not hold lock operation y does not access balance operations commute

S0 S1 S2 S3 S4 S7S6S5

acq(this) r=bal bal=r+n rel(this)x y z

S0 T1 T2 T3 S4 S7T6S5

acq(this) r=bal bal=r+n rel(this)x y z

S0 T1 S2 T3 S4 S7S6S5

y r=bal bal=r+n rel(this)x acq(this) z

S0 T1 T2 T3 S4 S7S6S5

acq(this) r=bal bal=r+n rel(this)x y z

Reduction (Lipton 76)Reduction (Lipton 76)

S0 S1 S2 T3 S4 S7S6S5

acq(this) r=bal bal=r+n rel(this)y zx

blue thread holds lock after acquire operation x does not modify lock operations commute

Page 18: Types for Atomicity in Multithreaded Software Shaz Qadeer Microsoft Research (Joint work with Cormac Flanagan)

Type System for Atomicity•Assign to each statement an atomicity that characterizes the statement’s behavior– five atomicities: R, L, B, A, C– does the statement left or right commute

with steps of other threads?– is the statement atomic?

Page 19: Types for Atomicity in Multithreaded Software Shaz Qadeer Microsoft Research (Joint work with Cormac Flanagan)

B: both right + left commutes– variable access holding lock

A: atomic action, non-commuting

– access unprotected variable

Five Atomicities

•R: right commutes– lock acquire

S0 S1 S2

acq(this) x

S0 T1 S2

x acq(this)

S7T6S5

rel(this) z

S7S6S5

rel(this)z

L: left commutes– lock release

C: compound, non-atomic statement

S2 S3 S4

r=bal y

S2 T3 S4

r=baly

S2 T3 S4

r=bal x

S2 S3 S4

r=balx

Page 20: Types for Atomicity in Multithreaded Software Shaz Qadeer Microsoft Research (Joint work with Cormac Flanagan)

Sequentially Composing Atomicities

Use atomicities to perform reduction Lipton: any sequence R*;A;L* is atomic

CCCCCCCCCAAACCCLLLCARARRCARLBBCARLB; R; B ; A; L

; A

AR

R;A;L ; R;A;L ; A

CA

S0. S5

R* A L*x Y. . .

S0. S5

R* A L*x Y. . .

Page 21: Types for Atomicity in Multithreaded Software Shaz Qadeer Microsoft Research (Joint work with Cormac Flanagan)

Atomicities for Conditionals

If E has atomicity aeand S1 has atomicity a1and S2 has atomicity a2 then

if (E) S1 else S2

has atomicity

ae ; (a1 a2)

L

A

B

R

C

Page 22: Types for Atomicity in Multithreaded Software Shaz Qadeer Microsoft Research (Joint work with Cormac Flanagan)

int balance;

Bank account

/*# atomicity A */void deposit (int x) { acquire(this); int r = balance; balance = r + x; release(this);}

/*# atomicity A */int read( ) { int r; acquire(this); r = balance; release(this); return r;}

/*# atomicity A */void withdraw(int x) { int r = read( ); acquire(this); balance = r – x; release(this);}

RBBL

RBLB

ARBL

AA

A

/*# guarded_by this */

Page 23: Types for Atomicity in Multithreaded Software Shaz Qadeer Microsoft Research (Joint work with Cormac Flanagan)

int balance;

Bank account

/*# atomicity A */void deposit (int x) { acquire(this); int r = balance; balance = r + x; release(this);}

/*# atomicity A */int read( ) { int r; acquire(this); r = balance; release(this); return r;}

/*# atomicity A */void withdraw(int x) { acquire(this); int r = balance; balance = r – x; release(this);}

RBBL

RBLB

RBBL

AA

A

/*# guarded_by this */

Page 24: Types for Atomicity in Multithreaded Software Shaz Qadeer Microsoft Research (Joint work with Cormac Flanagan)

int balance;

Bank account

/*# atomicity A */void deposit (int x) { acquire(this); int r = balance; balance = r + x; release(this);}

/*# atomicity A */int read( ) { return balance;}

/*# atomicity A */void withdraw(int x) { acquire(this); int r = balance; balance = r – x; release(this);}

RBAL

RBAL

A A

A

/*# write_guarded_by this */

Page 25: Types for Atomicity in Multithreaded Software Shaz Qadeer Microsoft Research (Joint work with Cormac Flanagan)

Conditional atomicitypublic class Vector … {

public boolean synchronized removeElement(Object obj) { modCount++; int i = indexOf(obj); if (i >= 0) { removeElementAt(i); return true; } return false;}

public int synchronized indexOf(Object elem) { … }

public void synchronized removeElementAt(int index) { … }…}

Page 26: Types for Atomicity in Multithreaded Software Shaz Qadeer Microsoft Research (Joint work with Cormac Flanagan)

Conditional atomicitypublic class Vector … {

/*# atomicity A */public boolean synchronized removeElement(Object obj) { modCount++; int i = indexOf(obj); if (i >= 0) { removeElementAt(i); return true; } return false;}

/*# atomicity A */public int synchronized indexOf(Object elem) { … }

/*# atomicity A */public void synchronized removeElementAt(int index) { … }…}

Page 27: Types for Atomicity in Multithreaded Software Shaz Qadeer Microsoft Research (Joint work with Cormac Flanagan)

Conditional atomicitypublic class Vector … {

/*# atomicity A */public boolean synchronized removeElement(Object obj) { modCount++; A int i = indexOf(obj); if (i >= 0) { A removeElementAt(i); return true; } return false;}

/*# atomicity A */public int synchronized indexOf(Object elem) { … }

/*# atomicity A */public void synchronized removeElementAt(int index) { … }…}

Unable to prove atomicity of removeElement !

Page 28: Types for Atomicity in Multithreaded Software Shaz Qadeer Microsoft Research (Joint work with Cormac Flanagan)

Conditional atomicitypublic class Vector … {

/*# atomicity A */public boolean synchronized removeElement(Object obj) { modCount++; int i = indexOf(obj); if (i >= 0) { removeElementAt(i); return true; } return false;}

/*# conditional_atomicity this ? B : A */public int synchronized indexOf(Object elem) { … }

/*# conditional_atomicity this ? B : A */public void synchronized removeElementAt(int index) { … }…}

Page 29: Types for Atomicity in Multithreaded Software Shaz Qadeer Microsoft Research (Joint work with Cormac Flanagan)

Conditional atomicitypublic class Vector … {

/*# atomicity A */public boolean synchronized removeElement(Object obj) { modCount++; B int i = indexOf(obj); if (i >= 0) { B removeElementAt(i); return true; } return false;}

/*# conditional_atomicity this ? B : A */public int synchronized indexOf(Object elem) { … }

/*# conditional_atomicity this ? B : A */public void synchronized removeElementAt(int index) { … }…}

Page 30: Types for Atomicity in Multithreaded Software Shaz Qadeer Microsoft Research (Joint work with Cormac Flanagan)

Soundness Theorem

• Suppose an interleaved execution of a well-typed program reaches state S where no thread is executing an atomic method in S

• Then there is a non-interleaved execution of the program that also reaches S

• Details in TLDI 03 and PLDI 03

Page 31: Types for Atomicity in Multithreaded Software Shaz Qadeer Microsoft Research (Joint work with Cormac Flanagan)

Atomicity Checker for Java

• Leverage Race Condition Checker to check that protecting lock is held when variables accessed

• Found several atomicity violations – java.lang.StringBuffer – java.lang.String– java.net.URL

Page 32: Types for Atomicity in Multithreaded Software Shaz Qadeer Microsoft Research (Joint work with Cormac Flanagan)

Experience with Atomicity Checker

ClassSize

(lines)

Annotations per KLOCtotal guar

dreq

.atomi

carray esc

.

Inflater 296 20 17 0 3 0 0

Deflater 364 25 20 0 5 0 0

PrintWriter 557 36 5 0 25 0 5

Vector 1029 14 3 1 4 3 3

URL 1269 33 10 1 10 0 13

StringBuffer 1272 19 2 4 5 7 1

String 2399 22 0 0 1 19 1

Total 7366 24 8 1 8 4 3

Page 33: Types for Atomicity in Multithreaded Software Shaz Qadeer Microsoft Research (Joint work with Cormac Flanagan)

Conclusions

• Programmers want conceptual atomicity of fine-grained computation

Page 34: Types for Atomicity in Multithreaded Software Shaz Qadeer Microsoft Research (Joint work with Cormac Flanagan)

Conclusions

• Programmers want conceptual atomicity of fine-grained computation

• Notion of atomicity is useful – code documentation – simplifies formal (and informal)

reasoning

Page 35: Types for Atomicity in Multithreaded Software Shaz Qadeer Microsoft Research (Joint work with Cormac Flanagan)

“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.”

“String buffers are atomic”

Page 36: Types for Atomicity in Multithreaded Software Shaz Qadeer Microsoft Research (Joint work with Cormac Flanagan)

Conclusions

• Programmers want conceptual atomicity of fine-grained computation

• Notion of atomicity is useful – code documentation – simplifies formal (and informal)

reasoning

• Race-freedom is neither necessary nor sufficient for atomicity