Presentation is loading. Please wait.

Presentation is loading. Please wait.

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

Similar presentations


Presentation on theme: "Types for Atomicity in Multithreaded Software Shaz Qadeer Microsoft Research (Joint work with Cormac Flanagan)"— Presentation transcript:

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

2 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

3 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

4 Multithreaded Program Execution Thread 1... int t1 = hits; hits = t1 + 1...   t2=hitshits=t2+1t1=hitshits=t1+1    hits=0 hits=2  t2=hits hits=t2+1 t1=hitshits=t1+1     hits=0 hits=1   t2=hitshits=t2+1t1=hits hits=t1+1     hits=0 hits=1  Thread 2... int t2 = hits; hits = t2 + 1...

5 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 write Thread 1... int t1 = hits; hits = t1 + 1... Thread 2... int t2 = hits; hits = t2 + 1...

6 Preventing Race Conditions Using 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 variable Thread 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

7 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

8 int balance; Race-free bank account void deposit (int n) { synchronized (this) {; balance = balance + n; }

9 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

10 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; }

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

12 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(...) {... } }

13 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!

14 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?

15 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

16 Definition of Atomicity deposit is atomic if for every interleaved execution, there is a non-interleaved execution with the same behavior         acq(this)r=balbal=r+nrel(this)xyz         acq(this)r=balbal=r+nrel(this)xyz         acq(this)r=balbal=r+nrel(this)xyz  Non-interleaved execution of deposit  Interleaved executions of deposit

17 blue thread holds lock  red thread does not hold lock  operation y does not access balance  operations commute S0S0 S1S1 S2S2 S3S3 S4S4 S7S7 S6S6 S5S5 acq(this)r=balbal=r+nrel(this)xyz S0S0 T1T1 T2T2 T3T3 S4S4 S7S7 T6T6 S5S5 acq(this)r=balbal=r+nrel(this)xyz S0S0 T1T1 S2S2 T3T3 S4S4 S7S7 S6S6 S5S5 yr=balbal=r+nrel(this)xacq(this)z S0S0 T1T1 T2T2 T3T3 S4S4 S7S7 S6S6 S5S5 r=balbal=r+nrel(this)xyz Reduction (Lipton 76) S0S0 S1S1 S2S2 T3T3 S4S4 S7S7 S6S6 S5S5 acq(this)r=balbal=r+nrel(this)yz x blue thread holds lock after acquire  operation x does not modify lock  operations commute

18 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?

19  B : both right + left commutes –variable access holding lock  A : atomic action, non-commuting –access unprotected variable Five Atomicities R : right commutes –lock acquire S0S0 S1S1 S2S2 acq(this)x S0S0 T1T1 S2S2 x S7S7 T6T6 S5S5 rel(this)z S7S7 S6S6 S5S5 z  L : left commutes –lock release  C : compound, non-atomic statement S2S2 S3S3 S4S4 r=baly S2S2 T3T3 S4S4 y S2S2 T3T3 S4S4 x S2S2 S3S3 S4S4 x

20 Sequentially Composing Atomicities  Use atomicities to perform reduction  Lipton: any sequence R* ; A ; L* is atomic CCCCCC CCCAAA CCCLLL CARARR CARLBB CARLB; R ; B ; A ; L ; A A R R ; A ; L ; R ; A ; L ; A C A S0S0. S5S5 R* A L*xY... S0S0. S5S5 R* A L* x Y...

21 Atomicities for Conditionals If E has atomicity ae and S1 has atomicity a1 and S2 has atomicity a2 then if (E) S1 else S2 has atomicity ae ; (a1  a2) L A B R C

22 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); } RBBLRBBL RBLBRBLB ARBLARBL AA A /*# guarded_by this */

23 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); } RBBLRBBL RBLBRBLB RBBLRBBL AAA /*# guarded_by this */

24 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); } RBALRBAL RBALRBAL AA A /*# write_guarded_by this */

25 Conditional atomicity public 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) { … } … }

26 Conditional atomicity public 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) { … } … }

27 Conditional atomicity public 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 !

28 Conditional atomicity public 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) { … } … }

29 Conditional atomicity public 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) { … } … }

30 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

31 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

32 Experience with Atomicity Checker Class Size (lines) Annotations per KLOC totalguardreq.atomicarrayesc. Inflater29620170300 Deflater36425200500 PrintWriter55736502505 Vector10291431433 URL126933101 013 StringBuffer12721924571 String239922001191 Total73662481843

33 Conclusions Programmers want conceptual atomicity of fine-grained computation

34 Conclusions Programmers want conceptual atomicity of fine-grained computation Notion of atomicity is useful –code documentation –simplifies formal (and informal) reasoning

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

36 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


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

Similar presentations


Ads by Google