Atomicity in Multithreaded Software Cormac Flanagan UC Santa Cruz C. Flanagan Atomicity in Multithreaded Software
Multithreaded Software Multithreading increasingly ubiquitous Current software lock-based synchronization painful, error prone, non-compositional Is there a better way transactions? yields transactions C. Flanagan Atomicity in Multithreaded Software
Race Conditions Race freedom is not sufficient to prevent errors A race condition occurs if two threads access a shared variable at the same time, and at least one of those accesses is a write int i; lock m; void inc() { acquire(m); int t = i; i = t+1; release(m); } int i; lock m; void inc() { acquire(m); int t = i; release(m); i = t+1; } race-free behaves correctly race-free behaves incorrectly Race freedom is not sufficient to prevent errors due to unexpected interactions between threads C. Flanagan Atomicity in Multithreaded Software
Atomicity in Multithreaded Software inc is atomic (serializable) if for each interleaved execution acq(m) t=i i=t+1 rel(m) x y z there is a serial execution with same behavior acq(m) t=i i=t+1 rel(m) x y z Atomicity simplifies method specifications informal: /* inc() increments i */ formal: ensures i == \old(i)+1 Atomicity methods are extremely common in existing code Atomicity enables sequential reasoning, simplifying: informal reasoning code inspection testing static analysis model checking formal verification C. Flanagan Atomicity in Multithreaded Software
Atomicity in Multithreaded Software Verifying Atomicity int i; lock m; void inc() { acquire(m); int t = i; i = t+1; release(m); } synchronization specification atomic Atomicity checkers synchronization implementation C. Flanagan Atomicity in Multithreaded Software
Experimental results: Atomicity in Java Most methods are atomic Most code will be transactional, many transactions will be long Protected locks common Nested transactions will be common Client-side locking common Code must work in transactions & non-transactional contexts C. Flanagan Atomicity in Multithreaded Software
java.lang.StringBuffer /** ... String buffers are safe for use by multiple threads. The methods are synchronized so that ... [atomic] */ class StringBuffer { private int count; synchronized int length() { return count; } synchronized void getChars(...) { ... } atomic synchronized void append(StringBuffer sb){ int len = sb.length(); ... sb.getChars(...,len,...); } StringIndexOutOfBoundsException C. Flanagan Atomicity in Multithreaded Software
java.lang.StringBuffer /** ... String buffers are safe for use by multiple threads. The methods are synchronized so that ... [atomic] */ class StringBuffer { private int count; synchronized int length() { return count; } synchronized void getChars(...) { ... } atomic synchronized void append(StringBuffer sb){ synchronized (sb) { int len = sb.length(); ... sb.getChars(...,len,...); } Deadlock C. Flanagan Atomicity in Multithreaded Software
Atomicity in Multithreaded Software Conclusions Current software is already “transactional” (via clumsy, error-prone locking) most code is transactional some transactions are long nested transactions are common Need to support modular software architectures C. Flanagan Atomicity in Multithreaded Software