Академический Документы
Профессиональный Документы
Культура Документы
Rice Computer Science Club Mathias Ricken Rice University October 4, 2007
Moores Law
Timeliness
CPU clock frequencies stagnate Multi-Core CPUs provide additional processing power
Multiple threads needed to use multiple cores
Programming Examples
Unit Testing
Unit tests
Test a part, not the whole program Occur earlier Automate testing Serve as documentation Prevent bugs from reoccurring Help keep the shared repository clean
Failure
Possible Solutions
Programming Language Features
Ensuring that bad things cannot happen May restrict programmers
Lock-Free Algorithms
Ensuring that if bad things happen, its ok May limit data structures available
Comprehensive Testing
Testing if bad things happen in any schedule Does not prevent problems, but does not limit solutions either
Contributions
Improvements to JUnit
Detect exceptions and failed assertions in threads other than the main thread
Improvements to JUnit
Uncaught exceptions and failed assertions
Not caught in child threads
test
success!
Child thread
Improvements to JUnit
Uncaught exceptions and failed assertions
Not caught in child threads
Child thread
Improvements to JUnit
Uncaught exceptions and failed assertions
Not caught in child threads
Detection of uncaught exceptions and failed assertions in child threads that occurred before tests end
Past tense: occurred!
Child thread
Improvements to JUnit
Child threads are not required to terminate
A test may pass before an error is reached
Enforced Join
public class Test extends TestCase { public void testException() { Thread t = new Thread(new Runnable() { new Thread(new Runnable() { public void run() { public void run() { throw new RuntimeException("booh!"); throw new RuntimeException("booh!"); throw new RuntimeException("booh!"); } } }); }); t.start(); t.join(); t.start(); t.join(); Child } thread }
Test thread
Improvements to JUnit
Child threads are not required to terminate
A test may pass before an error is reached
Testing ConcJUnit
Replacement for junit.jar or as plugin JAR for JUnit 4.2 Available as binary and source at http://www.concutest.org/ Results from DrJavas unit tests
Child thread for communication with slave VM still alive in test Several reader and writer threads still alive in low level test (calls to join() missing)
Conclusion
Improved JUnit now detects problems in other threads
Only in chosen schedule Needs schedule-based execution
Future Work
Schedule-Based Execution
Replay given schedule Generate possible schedules Dynamic race detection Probabilities/durations for random yields/sleeps
Many Thanks To
My advisor
Corky Cartwright
My committee members
Walid Taha Bill Scherer
Extra Slides
detail
back
lock
Thread 1
access unlock
Shared Var
Lock All accesses protected by lock lock access unlock All accesses protected by lock
Thread 2
Local Var 1
Fewer Schedules
Fewer critical points than thread switches
Reduces number of schedules Example: Two threads, but no communication N=1
Limitations
Improvements only check chosen schedule
A different schedule may still fail Requires comprehensive testing to be meaningful
Extra: Limitations
May still miss uncaught exceptions
Specify absolute parent thread group, not relative (rare)
Koders.com: 913 matches ThreadGroup vs. 49,329 matches for Thread
Cannot detect uncaught exceptions in a programs uncaught exception handler (JLS limitation)
Koders.com: 32 method definitions for uncaughtException method
back
Unit tests passed failed not run Invariants met failed % failed KLOC event thread
Concurrency Invariants
Has to be called in event thread
TableModel, TreeModel
Often not documented at all Errors not immediately evident Impossible to check automatically
Java Annotations
Add invariants as annotations
@NotEventThread public static void invokeAndWait( Runnable r) { }
Advantages of Annotations
Java Language constructs
Syntax checked by compiler
Light-weight
Negligible runtime impact if not debugging (slightly bigger class files)
Automatic Checking
Predicate Annotations
In annotation definition, specify static boolean Java method
Method must be callable from every context completely static and public
Data in annotation, method arguments and value of this passed when method invoked
Call
public class Predicates { public static boolean example( Object this0, int param, String foo) { return (foo.length()<param); // this0==t, param==5, foo=="test" }
Annotation Subclasses?
Let annotation extend a supertype?
public @interface Invariant { } public @interface OnlyThreadWithName extends Invariant { String name(); } public @interface And extends Invariant { Invariant[] terms(); }
Generic Annotations?
Write @And as generic annotation?
public @interface And<T> { T[] terms(); } public @interface OnlyThreadWithName { String name(); }
Work-Around
Different meta-annotation, @Combine
@Combine(Combine.Mode.AND) public @interface SeveralNames { OnlyThreadWithName[] value(); } @SeveralNames({@OnlyThreadWithName("foo"), @OnlyThreadWithName("bar")}) void testMethod() { }
Combine Annotations
May only contain invariant annotations
Predicate annotations Combine annotations Arrays of the above
Invariant Inheritance
Invariants on a method
Apply to the method and all overriding methods in subclasses
Invariants on a class
Apply to all methods introduced in that class or subclasses
All annotations describe requirements for the client (and, due to subclassing, for subclasses)
Allows frameworks to describe requirements Description thread-safe is often wrong
Invariant Subtyping
To maintain substitutability, subclasses may not strengthen invariants Invariants can be modeled as special input parameter
Tuple of invariants (record in calculus [Pierce]) Subtyping rules for records declare the wider record as subtype In function types, parameter types are contravariant
Invariant Subtyping
Analyze methods with invariants as parameter
class A { class B extends A { @Inv1 void f() { }; } class C extends B { @Inv2 void f() { }; }
void f() { };
Invariants subtyping:
A <@ B <@ C
Java subtyping:
C <: B <: A