1 / 11

Modular Typestate Checking for Concurrent Java Programs

Modular Typestate Checking for Concurrent Java Programs. Nels E. Beckman Carnegie Mellon University (Advised by Jonathan Aldrich). Problem: Check-then-Act Races. void pass() { final OnePlaceBuffer <String> b = new OnePlaceBuffer <String>(); b.put ( "Welcome to OOPSLA!" );

shaw
Download Presentation

Modular Typestate Checking for Concurrent Java Programs

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Modular Typestate Checking for Concurrent Java Programs Nels E. Beckman Carnegie Mellon University (Advised by Jonathan Aldrich)

  2. Problem: Check-then-Act Races void pass() { finalOnePlaceBuffer<String> b = newOnePlaceBuffer<String>(); b.put("Welcome to OOPSLA!"); shareWithNewThread(b); if( b.isFull() ) print(b.get()); } voidshareWithNewThread(OnePlaceBuffer<String> b) { new Thread() { if( b.isFull() ) print(b.get()); }.start(); } classOnePlaceBuffer<T> { T item = null; public synchronized booleanisFull() {...} public synchronized void put(T item) {...} public synchronized T get() { if(item==null) throw new Empty(); T result = item; item = null; return result; } }

  3. Approach: Specification & Access Permissions • Programmers define abstract states & transitions • (Implicitly with PRE- and POST-conditions) • Specifications also include access permissions • Describe aliasing, approximates thread sharing • Checked for consistency • Statically track states of refs to objects that cannot be concurrently modified • If mutual exclusion is used, temporarily track states of refs to object that can be

  4. 1 – Define Protocol via Specification classOnePlaceBuffer<T> { @Spec(ensures=“EMPTY”) publicOnePlaceBuffer(){…} @TrueIndicates(“FULL”) @FalseIndicates(“EMPTY”) public synchronized booleanisFull() {…} @Spec(requires=“EMPTY”,ensures=“FULL”) public synchronized void put(T item) {…} @Spec(requires=“FULL”, ensures=“EMPTY”) public synchronized T get() {…} }

  5. 2 – Access Permissions • Static information, specified for each reference, tracked by analysis • Does reference point to aliased object? • Does ref. have the right to modify? Do other refs.? • Approximates thread-sharedness • Five different kinds of permission unique(ref) – “At runtime, ref will be the only reference pointing to the object.” immutable(ref) – “ref points to an aliased object, but no reference can modify it.” full(ref) – “ref points to an aliased object, that will only be modified through ref.” pure(ref) – “ref points to an aliased object, that it cannot be used to modify. Other modifying references may exist!” share(ref) – “ref points to an aliased object and can be used to modify that object. Other modifying references may exist!”

  6. 2 – Adding Access Permissions to Spec. classOnePlaceBuffer<T> { @Unique(ensures=“EMPTY”) publicOnePlaceBuffer(){…} @Pure @TrueIndicates(“FULL”) @FalseIndicates(“EMPTY”) synchronized booleanisFull() {…} @Share(requires=“EMPTY”, ensures=“FULL”) synchronized void put(T item) {…} @Share(requires=“FULL”, ensures=“EMPTY”) public synchronized T get() {…} } void pass() { finalOnePlaceBuffer<String> b = newOnePlaceBuffer<String>(); b.put("Welcome to OOPSLA!"); shareWithNewThread(b); if( b.isFull() ) print(b.get()); } voidshareWithNewThread( @Share(returned=“false”) OnePlaceBuffer<String> b) { new Thread() { if( b.isFull() ) print(b.get()); }.start(); }

  7. 3 – Tracking States on References voidshareWithNewThread( @Share(returned=“false”) OnePlaceBuffer<String> b) { new Thread() { // Context: share(b) in ? if( b.isFull() ) // Context: share(b) in ? print(b.get()); }.start(); } Recall: share(ref) – “ref points to an aliased object and can be used to modify that object. Other modifying references may exist!” Assuming that other refs are reachable from other threads… We must assume concurrent modification! // ERROR

  8. 4 – Using Mutual Exclusion voidshareWithNewThread( @Share(returned=“false”) OnePlaceBuffer<String> b) { new Thread() { synchronized(b) { // Context: share(b) in ? if( b.isFull() ) // Context: share(b) in FULL print(b.get()); // Context: share(b) in EMPTY } }.start(); }

  9. Not Covered in this Talk… • Verification of Implementation • Ensures correct synchronization internally • Rules for Subtyping • Ensuring that subtype specs are compatible • Dimensions • Allow states and permissions to reference sub-sets of an object • State Hierarchies • Hierarchical state refinement • Fractions • Allow weaker permissions (e.g., share) to be statically combined to form stronger permissions (e.g., unique)

  10. Related Work • Fractional Permissions • Boyland • Ownership Types • Jacobs et al • Concurrent Separation Logic • O’Hearn • Single-threaded permissions • Bierhoff et al • (Unsound in multi-threaded programs)

  11. Contributions • Going beyond static data race detection • Preventing application-specific, check-then-act races • Extends single-threaded work with no additional specification burden • For S.R.C. • Extended approach to support synchronized blocks

More Related