Title: Verifiable Concurrent Programming Using Concurrency Controllers
1Verifiable Concurrent Programming Using
Concurrency Controllers
- Aysu Betin-Can and Tevfik Bultan
- University of California, Santa Barbara
- aysu,bultan_at_cs.ucsb.edu
2Motivation
- Concurrent programming is difficult
- Usage of synchronized, wait, notify, notifyAll is
error-prone - Assuring reliability of concurrent programs is
challenging - Can we have a structure for the concurrent
programs that - Makes them amenable to automated verification
- Enables to define customized synchronization
policies
3Concurency Controller Pattern
- A Verifiable behavioral design pattern for
concurrent systems - Defines customized synchronization policies
- Avoids usage of error-prone Java synchronization
primitives - Separates controller behavior from the threads
that use the controller - A Modular Verification Approach
- Exploits this modularity for scalability
- Case Study Concurrent Editor
4Concurrent Editor
ltltRMIgtgt
5Concurrent Editor
6Design Forces
- The synchronization policies should be pluggable
- Shared data classes should be maintainable
- There should be a mechanism to prevent
unnecessary context-switch among threads. - There should be a high-level synchronization
construct for implementing synchronization
policies which does not sacrifice efficiency. - The implementation should be verifiable
7Resolving the Forces
- The concurrency controller pattern separates the
synchronization operations from the operations
that change the shared object's internal state. - The synchronization policies should be pluggable
- Shared data classes should be maintainable
- The programs written based on this pattern are
supported with a verification technique - The implementation should be verifiable
8Resolving the Forces
- The concurrency controller pattern is supported
by an automated optimization technique based on
the Specific Notification Pattern Car96 - There should be a mechanism to prevent
unnecessary context-switch among threads. - There should be a high-level synchronization
construct for implementing synchronization
policies which does not sacrifice efficiency.
9Pattern Class Diagram
ThreadA
SharedInterface
ThreadB
transition() assert(state)s
a() assert(contr.state)
int
10Reader-Writer Controller
class Action protected final Object owner
private boolean GuardedExecute() boolean
resultfalse for(int i0 iltgcV.size()
i) try if(((GuardedCommand)gcV.get(i
)).guard()) ((GuardedCommand)gcV.get(i))
.update() resulttrue break
catch(Exception e) return result
public void blocking() synchronized(owner)
while(!GuardedExecute())
tryowner.wait()catch (Exception e)
owner.notifyAll() public boolean
nonblocking() synchronized(owner) boolean
resultGuardedExecute() if (result)
owner.notifyAll() return result
- class RWController implements RWInterface
- int nR boolean busy
- final Action act_r_enter, act_r_exit
- final Action act_w_enter, act_w_exit
- RWController() ...
- gcs new Vector()
- gcs.add(new GuardedCommand()
- public boolean guard()
- return (nR 0 !busy )
- public void update()busy true )
- act_w_enter new Action(this,gcs)
-
-
- public void w_enter() act_w_enter.blocking()
- public boolean w_exit()
- return act_w_exit.nonblocking()
- public void r_enter() act_r_enter.blocking()
- public boolean r_exit()
- return act_r_exit.nonblocking()
11ThreadA
ThreadB
Shared
RWController
Action
r_enter
blocking
blocking
r_enter
w_enter
blocking
peek
peek
r_exit
nonblocking
nonblocking
r_exit
blocking
w_enter
write
12Concurrency Controller Interface
- Defines the acceptable call sequences for the
threads that use the controller - Specified using finite state machines
- public class RWStateMachine implements
RWInterface - StateTable stateTable
- final static int idle0, reading1, writing2
- public RWStateMachine() ...
- stateTable.insert("w_enter",idle,writing)
-
- public void w_enter()
- stateTable.transition("w_enter")
-
- ...
-
13Sample Interfaces
leave
(a) Reader-Writer
(b) BB-Mutex
(d) Airport Ground Traffic Control
(c) Barrier
14Optimizing Concurrency Controllers
- Possible inefficiencies
- After every action execution in the controller
all the waiting threads are awakened - The inner classes and the large number of method
invocations may degrade the performance - Solution Generate an optimized controller
automatically - Optimized controller
- uses the specific notification pattern
- does not have any inner classes
- reduces the number of method invocations
15Verification Technique
- Utilizes behavior and interface decoupling in the
pattern - Behavior verification
- Verify the controller properties (e.g. safety,
liveness) - Assuming that the user threads adhere to the
controller interface - Interface verification
- Check that each user thread obeys the interface
- A thread is correct with respect to an interface
if all the call sequences generated by the thread
can also be generated by the finite state machine
defining the interface.
16System Architecture
Counting Abstraction
Behavior Specification in Action Language
Java Controller Class Controller Interface
Behavior Translator
Notification-Optimizer
Optimized Java Code
Data Stubs
Program with Stubs
Stub Substitution
Java PathFinder
Multi-threaded Program
Verified
Error Trace
17Behavior Verification
- Verification tool Action Language Verifier
- Infinite state symbolic model checker
- Advantages Can verify controllers
- With parameterized constants and unbounded
variables - For arbitrary number of user threads
- Tool usage Automated specification generation
from the controller classes
18Interface Verification
- Verification tool Java PathFinder (JPF)
- Explicit state program checker for Java
- Advantages Can check arbitrary thread
implementations without any restrictions - Tool usage Feed the prepared program to JPF and
look for assertion violations
19Interface Verification Preparation
- Replace the instances of the controllers with the
corresponding stubs - i.e., the interface state machines
- Replace the shared data protected by these
controllers with data stubs - Does a user thread access shared data only when
it is in a correct interface state? - Significant reduction in state space
20Interface Verification (Contd)
- Thread localization assumption
- threads only interact through controllers and the
shared data that are protected by these
controllers - Close the environment of a thread with controller
stubs and shared data stubs - Check each thread implementation separately
21Concurrent Editor
- 2800 lines of Java code with
- 17 class files,
- 5 controller classes,
- 7 Java interfaces
- Implemented without writing any Java
synchronization operations.
22ltltRMIgtgt
1
1
ltltRMIgtgt
23Case Study Interface Verification
- Handling RMI methods isolation
- Drivers simulating incoming calls to this node
- Stubs simulating outgoing calls to other node
- Handling GUI interactions
- Driver simulates the user interactions
- Event Thread creates Worker threads
- Less abstraction in data stubs for Event Thread
24Verification Results
- Errors discovered (interface violation errors)
- Caused by not calling the correct controller
method before accessing the shared data - Violation of the controller call sequence because
of the incorrectly handled exception blocks
25Verification Results
26Comparison with JPF
JPF only
Our Modular Approach
27Related Work
- Exploiting the properties of the design patterns
in verification, Mehlitz et al. 03 - Design patterns for multi-threaded systems,
- Schmidt et al.00Lea99Grand02Silva et
al. 96 - Writing reliable concurrent program
- Synthesizing synchronization code, Deng et
al.02 - Interface compatibility, Chakrabarti et al 02
- Monitor verification
- Magee Kramer 99, Yavuz-Kahveci Bultan
02 - Environment generation for Model checking
- Tkachuck et al 03, Giannakopoulou 04
28Conclusion
- Concurrency Controller Pattern
- A verifiable design pattern for concurrent
systems - Separates controller behavior from the threads
that use the controller - A Modular Verification approach
- Exploits the modularity in the pattern for
scalability - Behavior verification with Action Language
Verifier - Interface verification with Java PathFinder
- Using controller interfaces as stubs improves the
efficiency of the interface verification
significantly - Our approach is scalable to large, realistic
systems
29Questions?
30Verified Properties
31(No Transcript)
32Thread Correctness
- class Airplane extends Thread
- public Airplane(Airport a) airporta
- .
- private void arriving()
- airport.reqLand()
- airport.crossRW3()
-
- public void run()
- while(true) arriving()
-
Interface violation
Before crossRW3, exitRW3 should be executed
33Performance Results of our Approach
34Performance Results for JPF
35Related Work
- Design for Verification
- MP03, Mehlitz et al. promotes using design
patterns to build reliable software systems - Used in Circuit Design and Embedded Systems
- SF03, design for verification, white paper in
Synopsis Inc. - GSB02, Design for Verification at the Register
Transfer Level, in conf, on VLSI design - SBBCM01, Quality Electronic Design, 2001
International Symposium on electronic design
36Reader-Writer Controller
- class RWController implements RWInterface
- int nR boolean busy
- final Action act_r_enter, act_r_exit
- final Action act_w_enter, act_w_exit
- RWController() ...
- gcs new Vector()
- gcs.add(new GuardedCommand()
- public boolean guard()
- return (nR 0 !busy )
- public void update()busy true )
- act_w_enter new Action(this,gcs)
-
- public void w_enter() act_w_enter.blocking()
- public boolean w_exit()
- return act_w_exit.nonblocking()
- public void r_enter() act_r_enter.blocking()
- public boolean r_exit()
- return act_r_exit.nonblocking()
- class Action
- protected final Object owner
- private boolean GuardedExecute()
- boolean resultfalse
- for(int i0 iltgcV.size() i)
- try
- if(((GuardedCommand)gcV.get(i)).guard())
- ((GuardedCommand)gcV.get(i)).update()
- resulttrue break
- catch(Exception e)
- return result
-
- public void blocking()
- synchronized(owner)
- while(!GuardedExecute())
- tryowner.wait()catch (Exception e)
- owner.notifyAll()
-
- public boolean nonblocking()