A Parameterized Type System for Race-Free Java Programs Chandrasekhar Boyapati Martin Rinard Laboratory for Computer Science Massachusetts Institute of.

Slides:



Advertisements
Similar presentations
Bounded Model Checking of Concurrent Data Types on Relaxed Memory Models: A Case Study Sebastian Burckhardt Rajeev Alur Milo M. K. Martin Department of.
Advertisements

Goldilocks: Efficiently Computing the Happens-Before Relation Using Locksets Tayfun Elmas 1, Shaz Qadeer 2, Serdar Tasiran 1 1 Koç University, İstanbul,
Verification of Multithreaded Object- Oriented Programs with Invariants Bart Jacobs, K. Rustan M. Leino, Wolfram Schulte.
Eraser: A Dynamic Data Race Detector for Multithreaded Programs STEFAN SAVAGE, MICHAEL BURROWS, GREG NELSON, PATRICK SOBALVARRO and THOMAS ANDERSON.
1 Concurrency Specification. 2 Outline 4 Issues in concurrent systems 4 Programming language support for concurrency 4 Concurrency analysis - A specification.
Atomizer: A Dynamic Atomicity Checker For Multithreaded Programs Stephen Freund Williams College Cormac Flanagan University of California, Santa Cruz.
Types for Atomicity in Multithreaded Software Shaz Qadeer Microsoft Research (Joint work with Cormac Flanagan)
A Parameterized Type System for Race-Free Java Programs Paper by Boyapti & Rinard, 2001 Christopher Dentel ETH, Concepts of Concurrent Computation, 2012.
/ PSWLAB Atomizer: A Dynamic Atomicity Checker For Multithreaded Programs By Cormac Flanagan, Stephen N. Freund 24 th April, 2008 Hong,Shin.
CS 263 Course Project1 Survey: Type Systems for Race Detection and Atomicity Feng Zhou, 12/3/2003.
CS444/CS544 Operating Systems Synchronization 2/16/2006 Prof. Searleman
Concurrency and Thread Yoshi. Two Ways to Create Thread Extending class Thread – Actually, we need to override the run method in class Thread Implementing.
“THREADS CANNOT BE IMPLEMENTED AS A LIBRARY” HANS-J. BOEHM, HP LABS Presented by Seema Saijpaul CS-510.
C. FlanaganSAS’04: Type Inference Against Races1 Type Inference Against Races Cormac Flanagan UC Santa Cruz Stephen N. Freund Williams College.
Ownership Types for Safe Programming: Preventing Data Races and Deadlocks Chandrasekhar Boyapati Robert Lee Martin Rinard Laboratory for Computer Science.
Chandrasekhar Boyapati Laboratory for Computer Science Massachusetts Institute of Technology Ownership Types for Safe Programming.
Ownership Types for Object Encapsulation Barbara Liskov Chandrasekhar Boyapati Liuba Shrira Laboratory for Computer Science Massachusetts Institute of.
Programming Language Semantics Java Threads and Locks Informal Introduction The Java Specification Language Chapter 17.
A Type System for Preventing Data Races and Deadlocks in the Java Virtual Machine Language Pratibha Permandla Michael Roberson Chandrasekhar Boyapati University.
Laboratory for Computer Science Massachusetts Institute of Technology Ownership Types for Safe Region-Based Memory Management in Real-Time Java Chandrasekhar.
Compositional Pointer and Escape Analysis for Java Programs Martin Rinard Laboratory for Computer Science MIT John Whaley IBM Tokyo Research Laboratory.
Synchronization in Java Fawzi Emad Chau-Wen Tseng Department of Computer Science University of Maryland, College Park.
1 Sharing Objects – Ch. 3 Visibility What is the source of the issue? Volatile Dekker’s algorithm Publication and Escape Thread Confinement Immutability.
CS510 Concurrent Systems Class 5 Threads Cannot Be Implemented As a Library.
0wn3rship Types John Whaley CS343 Stanford University May 19, 2004.
Ownership Types for Object Encapsulation Authors:Chandrasekhar Boyapati Barbara Liskov Liuba Shrira Presented by: Charles Lin Course: CMSC 631.
Cormac Flanagan UC Santa Cruz Velodrome: A Sound and Complete Dynamic Atomicity Checker for Multithreaded Programs Jaeheon Yi UC Santa Cruz Stephen Freund.
Synchronization CSCI 444/544 Operating Systems Fall 2008.
/ PSWLAB Eraser: A Dynamic Data Race Detector for Multithreaded Programs By Stefan Savage et al 5 th Mar 2008 presented by Hong,Shin Eraser:
Learning From Mistakes—A Comprehensive Study on Real World Concurrency Bug Characteristics Shan Lu, Soyeon Park, Eunsoo Seo and Yuanyuan Zhou Appeared.
Discussion Week 3 TA: Kyle Dewey. Overview Concurrency overview Synchronization primitives Semaphores Locks Conditions Project #1.
C. FlanaganType Systems for Multithreaded Software1 Cormac Flanagan UC Santa Cruz Stephen N. Freund Williams College Shaz Qadeer Microsoft Research.
Analysis of Multithreaded Programs Martin Rinard Laboratory for Computer Science Massachusetts Institute of Technology.
Threading and Concurrency Issues ● Creating Threads ● In Java ● Subclassing Thread ● Implementing Runnable ● Synchronization ● Immutable ● Synchronized.
Eraser: A Dynamic Data Race Detector for Multithreaded Programs STEFAN SAVAGE, MICHAEL BURROWS, GREG NELSON, PATRICK SOBALVARRO, and THOMAS ANDERSON Ethan.
/ PSWLAB Type-Based Race Detection for J AVA by Cormac Flanagan, Stephen N. Freund 22 nd Feb 2008 presented by Hong,Shin Type-Based.
ROBERT BOCCHINO, ET AL. UNIVERSAL PARALLEL COMPUTING RESEARCH CENTER UNIVERSITY OF ILLINOIS A Type and Effect System for Deterministic Parallel Java *Based.
Foundations of the C++ Concurrency Memory Model Hans-J. Boehm Sarita V. Adve HP Laboratories UIUC.
COMP 111 Threads and concurrency Sept 28, Tufts University Computer Science2 Who is this guy? I am not Prof. Couch Obvious? Sam Guyer New assistant.
Colorama: Architectural Support for Data-Centric Synchronization Luis Ceze, Pablo Montesinos, Christoph von Praun, and Josep Torrellas, HPCA 2007 Shimin.
Aritra Sengupta, Swarnendu Biswas, Minjia Zhang, Michael D. Bond and Milind Kulkarni ASPLOS 2015, ISTANBUL, TURKEY Hybrid Static-Dynamic Analysis for Statically.
A Universe-Type-Based Verification Technique for Mutable Static Fields and Methods Alexander J Summers Sophia Drossopoulou Imperial College London Peter.
Sharing Objects  Synchronization  Atomicity  Specifying critical sections  Memory visibility  One thread’s modification seen by the other  Visibility.
Data races, informally [More formal definition to follow] “race condition” means two different things Data race: Two threads read/write, write/read, or.
November 2005Scott Stoller, Stony Brook University1 Detecting Potential Deadlocks with Static Analysis and Run-Time Monitoring Rahul Agarwal, Liqiang Wang,
SPL/2010 Synchronization 1. SPL/2010 Overview ● synchronization mechanisms in modern RTEs ● concurrency issues ● places where synchronization is needed.
Detecting and Eliminating Potential Violation of Sequential Consistency for concurrent C/C++ program Duan Yuelu, Feng Xiaobing, Pen-chung Yew.
ICFEM 2002, Shanghai Reasoning about Hardware and Software Memory Models Abhik Roychoudhury School of Computing National University of Singapore.
U NIVERSITY OF M ASSACHUSETTS A MHERST Department of Computer Science Computer Systems Principles Synchronization Emery Berger and Mark Corner University.
CoreDet: A Compiler and Runtime System for Deterministic Multithreaded Execution Tom Bergan Owen Anderson, Joe Devietti, Luis Ceze, Dan Grossman To appear.
Pointer and Escape Analysis for Multithreaded Programs Alexandru Salcianu Martin Rinard Laboratory for Computer Science Massachusetts Institute of Technology.
ReIm & ReImInfer: Checking and Inference of Reference Immutability and Method Purity Wei Huang 1, Ana Milanova 1, Werner Dietl 2, Michael D. Ernst 2 1.
Aritra Sengupta, Man Cao, Michael D. Bond and Milind Kulkarni PPPJ 2015, Melbourne, Florida, USA Toward Efficient Strong Memory Model Support for the Java.
Specifying Multithreaded Java semantics for Program Verification Abhik Roychoudhury National University of Singapore (Joint work with Tulika Mitra)
Eraser: A dynamic Data Race Detector for Multithreaded Programs Stefan Savage, Michael Burrows, Greg Nelson, Patrick Sobalvarro, Thomas Anderson Presenter:
Using Escape Analysis in Dynamic Data Race Detection Emma Harrington `15 Williams College
Synchronization Questions answered in this lecture: Why is synchronization necessary? What are race conditions, critical sections, and atomic operations?
Sung-Dong Kim, Dept. of Computer Engineering, Hansung University Java - Introduction.
1 Towards Automated Verification Through Type Discovery Joint work with Rahul Agarwal Scott D. Stoller State University of New York at Stony Brook.
Detecting Data Races in Multi-Threaded Programs
Healing Data Races On-The-Fly
Types for Programs and Proofs
Compositional Pointer and Escape Analysis for Java Programs
Threads Cannot Be Implemented As a Library
Threads and Memory Models Hal Perkins Autumn 2011
Atomicity in Multithreaded Software
Threads and Memory Models Hal Perkins Autumn 2009
Relaxed Consistency Finale
CSE 332: Concurrency and Locks
Object Encapsulation CSC 422 Dr. Spiegel.
Presentation transcript:

A Parameterized Type System for Race-Free Java Programs Chandrasekhar Boyapati Martin Rinard Laboratory for Computer Science Massachusetts Institute of Technology {chandra,

Data races in multithreaded programs Two threads concurrently access same data At least one access is a write No synchronization to separate accesses Thread 1: x = x + 1; Thread 2: x = x + 2;

Why data races are a problem Some correct programs contain data races But most races are programming errors Code intended to execute atomically Synchronization omitted by mistake Consequences can be severe Non-deterministic, timing-dependent bugs Difficult to detect, reproduce, eliminate

Avoiding data races Thread 1: x = x + 1; Thread 2: x = x + 2;

Avoiding data races Thread 1: lock(l); x = x + 1; unlock(l); Thread 2: lock(l); x = x + 2; unlock(l); Associate a lock with every shared mutable data Acquire lock before data access Release lock after data access

Avoiding data races Thread 1: lock(l); x = x + 1; unlock(l); Thread 2: lock(l); x = x + 2; unlock(l); Problem: Locking is not enforced! Inadvertent programming errors…

Our solution A static type system for OO programs Well-typed programs are free of races

Our solution A static type system for OO programs Well-typed programs are free of races Programmers specify How each object is protected from races In types of variables pointing to objects Type checkers statically verify That objects are used only as specified

Protection mechanism of an object Specifies the lock protecting the object, or Specifies that object needs no locks b’cos The object is immutable, or The object is not shared, or There is a unique pointer to the object

Types are proofs Type checker Translator (Removes extra types) Compiler JVM Java bytecodes + Extra types Java

Outline Motivation Type system Experience Related work Conclusions

Race-free Account program class Account { int balance = 0; int deposit(int x) { this.balance += x; } Account a1 = new Account; fork (a1) { synchronized (a1) in { a1.deposit(10); } }; Account a2 = new Account; a2.deposit(10);

Race-free Account program class Account { int balance = 0; int deposit(int x) { this.balance += x; } Account a1 = new Account; fork (a1) { synchronized (a1) in { a1.deposit(10); } }; Account a2 = new Account; a2.deposit(10); Thread t; t.start(); fork (t) { t.start(); } Java: Concurrent Java: 

Race-free Account program class Account { int balance = 0; int deposit(int x) { this.balance += x; } Account a1 = new Account; fork (a1) { synchronized (a1) in { a1.deposit(10); } }; Account a2 = new Account; a2.deposit(10);

Statically verifiable race-free program class Account  thisOwner  { int balance = 0; int deposit(int x) requires (this) { this.balance += x; } final Account  self  a1 = new Account  self  ; fork (a1) { synchronized (a1) in { a1.deposit(10); } }; Account  thisThread  a2 = new Account  thisThread  ; a2.deposit(10);

Statically verifiable race-free program thisOwner protects the Account class Account  thisOwner  { int balance = 0; int deposit(int x) requires (this) { this.balance += x; } final Account  self  a1 = new Account  self  ; fork (a1) { synchronized (a1) in { a1.deposit(10); } }; Account  thisThread  a2 = new Account  thisThread  ; a2.deposit(10);

Statically verifiable race-free program a1 is protected by its lock a2 is thread-local class Account  thisOwner  { int balance = 0; int deposit(int x) requires (this) { this.balance += x; } final Account  self  a1 = new Account  self  ; fork (a1) { synchronized (a1) in { a1.deposit(10); } }; Account  thisThread  a2 = new Account  thisThread  ; a2.deposit(10);

Statically verifiable race-free program class Account  thisOwner  { int balance = 0; int deposit(int x) requires (this) { this.balance += x; } final Account  self  a1 = new Account  self  ; fork (a1) { synchronized (a1) in { a1.deposit(10); } }; Account  thisThread  a2 = new Account  thisThread  ; a2.deposit(10); deposit requires lock on “this”

class Account  thisOwner  { int balance = 0; int deposit(int x) requires (this) { this.balance += x; } final Account  self  a1 = new Account  self  ; fork (a1) { synchronized (a1) in { a1.deposit(10); } }; Account  thisThread  a2 = new Account  thisThread  ; a2.deposit(10); Statically verifiable race-free program a1 is locked before calling deposit a2 need not be locked

Type system Basic type system: Locks, thread-local objects Object ownership Type system Type inference Extensions: Unique pointers, read-only objects

Object ownership Every object has an owner An object can be owned by Itself Another object Special per-thread owner called thisThread thisThread Thread2 objects Thread1 objects Potentially shared objects

Ownership properties Owner of an object does not change over time Ownership relation forms a forest of rooted trees Roots can have self loops thisThread Thread2 objects Thread1 objects Potentially shared objects

Ownership properties Every object is protected by its root owner To gain exclusive access to an object, it is Necessary and sufficient to lock its root owner A thread implicitly holds the lock on its thisThread thisThread Thread2 objects Thread1 objects Potentially shared objects

Basic type system Object ownership Type system Type inference

class TStack { TNode head; void push(T value) {…} T pop() {…} } class TNode { TNode next; T value; … } class T {…} TStack program value next head value next value next … … … TStack TNode’s T’s

TStack program class TStack  thisOwner, TOwner  { TNode  this, TOwner  head; … } class TNode  thisOwner, TOwner  { TNode  thisOwner, TOwner  next; T  TOwner  value; … } TStack  thisThread, thisThread  s1; TStack  thisThread, self  s2; TStack TNode’s T’s

Parameterizing classes Classes are parameterized with one or more owners First owner owns the “this” object class TStack  thisOwner, TOwner  { TNode  this, TOwner  head; … } class TNode  thisOwner, TOwner  { TNode  thisOwner, TOwner  next; T  TOwner  value; … } TStack  thisThread, thisThread  s1; TStack  thisThread, self  s2; TStack TNode’s T’s

Instantiating classes Classes can be instantiated with final expressions E.g., with “this” class TStack  thisOwner, TOwner  { TNode  this, TOwner  head; … } class TNode  thisOwner, TOwner  { TNode  thisOwner, TOwner  next; T  TOwner  value; … } TStack  thisThread, thisThread  s1; TStack  thisThread, self  s2; TStack TNode’s T’s

Instantiating classes Classes can be instantiated with formal parameters E.g., with “thisOwner” or “TOwner” class TStack  thisOwner, TOwner  { TNode  this, TOwner  head; … } class TNode  thisOwner, TOwner  { TNode  thisOwner, TOwner  next; T  TOwner  value; … } TStack  thisThread, thisThread  s1; TStack  thisThread, self  s2; TStack TNode’s T’s

Instantiating classes Classes can be instantiated with “thisThread” class TStack  thisOwner, TOwner  { TNode  this, TOwner  head; … } class TNode  thisOwner, TOwner  { TNode  thisOwner, TOwner  next; T  TOwner  value; … } TStack  thisThread, thisThread  s1; TStack  thisThread, self  s2; thisThread TStack TNode’s T’s

Instantiating classes Classes can be instantiated with “self” class TStack  thisOwner, TOwner  { TNode  this, TOwner  head; … } class TNode  thisOwner, TOwner  { TNode  thisOwner, TOwner  next; T  TOwner  value; … } TStack  thisThread, thisThread  s1; TStack  thisThread, self  s2; thisThread TStack TNode’s T’s

Requires clauses class TStack  thisOwner, TOwner  { TNode  this, TOwner  head; … T  TOwner  pop() requires (this) { if (head == null) return null; T  TOwner  value = head.value(); head = head.next(); return value; } class TNode  thisOwner, TOwner  { T  TOwner  value() requires (this) {…} TNode  thisOwner, TOwner  next() requires (this) {…} … } Methods can require threads to have locks on root owners of objects

Type checking pop method value next head value next value next … … … TStack TNode’s T’s class TStack  thisOwner, TOwner  { TNode  this, TOwner  head; … T  TOwner  pop() requires (this) { if (head == null) return null; T  TOwner  value = head.value(); head = head.next(); return value; } class TNode  thisOwner, TOwner  { T  TOwner  value() requires (this) {…} TNode  thisOwner, TOwner  next() requires (this) {…} … }

Type checking pop method Locks held thisThread, RootOwner(this) class TStack  thisOwner, TOwner  { TNode  this, TOwner  head; … T  TOwner  pop() requires (this) { if (head == null) return null; T  TOwner  value = head.value(); head = head.next(); return value; } class TNode  thisOwner, TOwner  { T  TOwner  value() requires (this) {…} TNode  thisOwner, TOwner  next() requires (this) {…} … }

Type checking pop method Locks held thisThread, RootOwner(this) Locks required RootOwner(this) class TStack  thisOwner, TOwner  { TNode  this, TOwner  head; … T  TOwner  pop() requires (this) { if (head == null) return null; T  TOwner  value = head.value(); head = head.next(); return value; } class TNode  thisOwner, TOwner  { T  TOwner  value() requires (this) {…} TNode  thisOwner, TOwner  next() requires (this) {…} … }

Type checking pop method Locks held thisThread, RootOwner(this) Locks required ? class TStack  thisOwner, TOwner  { TNode  this, TOwner  head; … T  TOwner  pop() requires (this) { if (head == null) return null; T  TOwner  value = head.value(); head = head.next(); return value; } class TNode  thisOwner, TOwner  { T  TOwner  value() requires (this) {…} TNode  thisOwner, TOwner  next() requires (this) {…} … }

Type checking pop method Locks held thisThread, RootOwner(this) Locks required RootOwner(head) class TStack  thisOwner, TOwner  { TNode  this, TOwner  head; … T  TOwner  pop() requires (this) { if (head == null) return null; T  TOwner  value = head.value(); head = head.next(); return value; } class TNode  thisOwner, TOwner  { T  TOwner  value() requires (this) {…} TNode  thisOwner, TOwner  next() requires (this) {…} … }

Type checking pop method Locks held thisThread, RootOwner(this) Locks required RootOwner(head) = RootOwner(this) class TStack  thisOwner, TOwner  { TNode  this, TOwner  head; … T  TOwner  pop() requires (this) { if (head == null) return null; T  TOwner  value = head.value(); head = head.next(); return value; } class TNode  thisOwner, TOwner  { T  TOwner  value() requires (this) {…} TNode  thisOwner, TOwner  next() requires (this) {…} … }

Type checking pop method Locks held thisThread, RootOwner(this) Locks required RootOwner(this), RootOwner(head) = RootOwner(this) class TStack  thisOwner, TOwner  { TNode  this, TOwner  head; … T  TOwner  pop() requires (this) { if (head == null) return null; T  TOwner  value = head.value(); head = head.next(); return value; } class TNode  thisOwner, TOwner  { T  TOwner  value() requires (this) {…} TNode  thisOwner, TOwner  next() requires (this) {…} … }

Type checking pop method class TStack  thisOwner, TOwner  { TNode  this, TOwner  head; … T  TOwner  pop() requires (this) { if (head == null) return null; T  TOwner  value = head.value(); head = head.next(); return value; } class TNode  thisOwner, TOwner  { T  TOwner  value() requires (this) {…} TNode  thisOwner, TOwner  next() requires (this) {…} … }

Type checking client code class TStack  thisOwner, TOwner  { T  TOwner  pop() requires (this) {…} … } final TStack  self, self  s = …; fork (s) { synchronized (s) in { s.pop(); } };

Type checking client code Locks held thisThread, s class TStack  thisOwner, TOwner  { T  TOwner  pop() requires (this) {…} … } final TStack  self, self  s = …; fork (s) { synchronized (s) in { s.pop(); } };

Type checking client code Locks held thisThread, s Locks required RootOwner(s) = s class TStack  thisOwner, TOwner  { T  TOwner  pop() requires (this) {…} … } final TStack  self, self  s = …; fork (s) { synchronized (s) in { s.pop(); } };

Basic type system Object ownership Type system Type inference

Inferring owners of local variables class A  oa1, oa2  {…} class B  ob1, ob2, ob3  extends A  ob1, ob3  {…} class C { void m(B  this, oc1, thisThread  b) { A a1; B b1; b1 = b; a1 = b1; }

Inferring owners of local variables class A  oa1, oa2  {…} class B  ob1, ob2, ob3  extends A  ob1, ob3  {…} class C { void m(B  this, oc1, thisThread  b) { A  x1, x2  a1; B  x3, x4, x5  b1; b1 = b; a1 = b1; } Augment unknown types with owners

Inferring owners of local variables Gather constraints x3 = this x4 = oc1 x5 = thisThread class A  oa1, oa2  {…} class B  ob1, ob2, ob3  extends A  ob1, ob3  {…} class C { void m(B  this, oc1, thisThread  b) { A  x1, x2  a1; B  x3, x4, x5  b1; b1 = b; a1 = b1; }

Inferring owners of local variables Gather constraints x3 = this x4 = oc1 x5 = thisThread x1 = x3 x2 = x5 class A  oa1, oa2  {…} class B  ob1, ob2, ob3  extends A  ob1, ob3  {…} class C { void m(B  this, oc1, thisThread  b) { A  x1, x2  a1; B  x3, x4, x5  b1; b1 = b; a1 = b1; }

class A  oa1, oa2  {…} class B  ob1, ob2, ob3  extends A  ob1, ob3  {…} class C { void m(B  this, oc1, thisThread  b) { A  this, thisThread  a1; B  this, oc1, thisThread  b1; b1 = b; a1 = b1; } Inferring owners of local variables Solve constraints x3 = this x4 = oc1 x5 = thisThread x1 = x3 x2 = x5

class A  oa1, oa2  {…} class B  ob1, ob2, ob3  extends A  ob1, ob3  {…} class C { void m(B  this, oc1, thisThread  b) { A  this, thisThread  a1; B  this, oc1, thisThread  b1; b1 = b; a1 = b1; } Inferring owners of local variables Solve constraints Only equality constraints between owners Takes almost linear time to solve x3 = this x4 = oc1 x5 = thisThread x1 = x3 x2 = x5

Default types To further reduce programming overhead Single threaded programs require almost no programming overhead

Outline Motivation Type system Experience Related work Conclusions

Multithreaded server programs ProgramLines of codeLines changed http server56326 chat server30821 stock quote server24212 game server 8710 phone (database) server30210

Java libraries ProgramLines of codeLines changed java.io.OutputStream13403 java.io.BufferedWriter25309 java.io.OutputStreamWriter26611 java.io.Writer17706 java.io.PrintStream56814 java.io.FilterOutputStream14805 java.util.Vector99235 java.util.ArrayList53318

Java libraries Java has two classes for resizable arrays java.util.Vector Self synchronized, do not create races Always incur synchronization overhead java.util.ArrayList No unnecessary synchronization overhead Could be used unsafely to create races We provide generic resizable arrays Safe, but no unnecessary overhead

Java libraries Java programs contain unnecessary locking Much analysis work to remove unnecessary locking Aldrich, Chambers, Sirer, Eggers ( SAS ‘99 ) Whaley, Rinard ( OOPSLA ‘99 ) Choi, Gupta, Serrano, Sreedhar, Midkiff ( OOPSLA ‘99 ) Blanchet ( OOPSLA ‘99 ) Bogda, Holzle ( OOPSLA ‘99 ) Ruf ( PLDI ‘00 ) Our implementation Avoids unnecessary locking Without sacrificing safety

Additional benefits of race-free types Data races expose the effects of Weak memory consistency models Standard compiler optimizations

What is the value of z? Thread 1: y=0; x=1; Thread 2: z=x+y; Initially: x=0; y=1;

What is the value of z? Thread 1: y=0; x=1; Thread 2: z=x+y; Initially: x=0; y=1; z=x+y; y=0; x=1; z=1 y=0; z=x+y; x=1; z=0 y=0; x=1; z=x+y; z=1 Possible Interleavings

What is the value of z? Thread 1: y=0; x=1; Thread 2: z=x+y; Initially: x=0; y=1; z=x+y; y=0; x=1; z=1 y=0; z=x+y; x=1; z=0 y=0; x=1; z=x+y; z=1 x=1; z=x+y; y=0; z=2 !!! Possible Interleavings Above instruction reordering legal in single-threaded programs Violates sequential consistency in multithreaded programs

Additional benefits of race-free types Data races expose effects of Weak memory consistency models Standard compiler optimizations Data races complicate program analysis Data races complicate human understanding Race-free languages Eliminate these issues Make multithreaded programming more tractable

Outline Motivation Type system Experience Related work Conclusions

Tools to detect races Static race detection systems Sterling ( USENIX ‘93 ) Detlefs, Leino, Nelson, Saxe ( SRC ‘98 ) Engler, Chen, Hallem, Chou, Chelf ( SOSP ‘01 ) Dynamic race detection systems Steele ( POPL ‘90 ) Dinning, Schonberg ( PPoPP ‘90 ) Savage, Burrows, Nelson, Sobalvarro, Anderson ( SOSP ‘97 ) Praun, Gross ( OOPSLA ’01 )

Type systems to prevent races Race-free Java Flanagan and Freund ( PLDI ’00 ) Guava Bacon, Strom, Tarafdar ( OOPSLA ’00 )

Other related type systems Ownership types Clarke, Potter, Noble ( OOPSLA ’98 ), ( ECOOP ’01 ) Region types Grossman, Morrisett, Jim, Hicks, Wang, Cheney ( Cornell‘01 ) Parameterized types for Java Myers, Bank, Liskov ( POPL ’97 ) Agesen, Freund, Mitchell ( OOPSLA ’97 ) Bracha, Odersky, Stoutamire, Wadler ( OOPSLA ’98 ) Cartwright, Steele ( OOPSLA ’98 )

Conclusions Data races make programs hard to debug We presented race-free static type system Our type system is expressive Programs can be reliable and efficient

A Parameterized Type System for Race-Free Java Programs Chandrasekhar Boyapati Martin Rinard Laboratory for Computer Science Massachusetts Institute of Technology {chandra,