Szumo: A Compositional Contract Model for Safe Multi- Threaded Applications LASER 2005 Laura K. Dillon Software Engineering & Network Systems Laboratory Michigan State University ldillon@cse.msu.edu Laser 2005 - Summer School on 1 Software Engineering
Credits ♦ Creators: Reimer Behrends, R. E. Kurt Stirewalt ♦ Financial Support: – US Department of the Navy, ONR grant N00014-01- 1-0744 – National Science Foundation grants EIA-0000433, CCR-9901017, CCR-9984727, CDA-9617310, and CCR-9896190 – US Defense Advance Research Projects Agency, DASADA program Laser 2005 - Summer School on 2 Software Engineering
Synchronization Units Model ♦ Problem: Synchronization concerns in multi- threaded object-oriented programs complicate designs – Difficult to modularize – A source of brittleness ♦ Goal: Facilitate extension, maintenance and evolution through better modularization of synchronization concerns ♦ Idea: Associate synchronization contracts with modules and automatically infer necessary synchronization logic from the contracts Laser 2005 - Summer School on 3 Software Engineering
Overview of lecture series ♦ Background ♦ Introduction to Szumo ♦ Case study ♦ Semantic and implementation details ♦ Related concurrency models ♦ Ongoing and future work Laser 2005 - Summer School on 4 Software Engineering
Overview of lecture series ♦ Background – Contracts – Multi-threaded OO programs – Concurrency problems ♦ Introduction to Szumo ♦ Case study ♦ Semantic and implementation details ♦ Related concurrency models ♦ Ongoing and future work Laser 2005 - Summer School on 5 Software Engineering
Contracts Formal Agreement between a supplier and its clients ♦ Parties have rights and responsibilities ♦ Improved documentation, verification, separation of concerns ♦ Can enable optimizations sqrt( x : REAL ) : REAL is Zen and the art of sw reliability: require guarantee more by checking less! x >= 0 do … end Laser 2005 - Summer School on 6 Software Engineering
Contract awareness ♦ Different degrees of strength [Beugnard et al.’99]: Degree of Contract Awareness Level 1: Level 2: Level 3: Level 4: Syntactic Behavioral Synchronization QOS Higher degrees: – Support contracting over non-functional properties – Enable dynamic client-supplier negotiation of services Laser 2005 - Summer School on 7 Software Engineering
Overview of lecture series ♦ Background – Contracts – Multi-threaded OO programs – Concurrency problems ♦ Introduction to Szumo ♦ Case study ♦ Semantic and implementation details ♦ Related concurrency models ♦ Ongoing and future work Laser 2005 - Summer School on 8 Software Engineering
Multi-threaded OO Program ♦ Multiple threads manipulate passive objects in shared memory ♦ Major concurrency concern: Threads within critical regions require exclusive access to shared objects ♦ Designer must identify and protect these critical regions without introducing concurrency errors (e.g., deadlock, starvation). Laser 2005 - Summer School on 9 Software Engineering
Example: Dining Philosophers Three philosophers sit around a circular table set with three forks and a large bowl of spaghetti. Each philosopher alternates between thinking and eating ad infinitum . To eat, a philosopher picks up the fork to her left and then the fork to her right. After eating, she returns the forks to their places and then proceeds to think. Laser 2005 - Summer School on 10 Software Engineering
Example: Dining Philosophers in Java Class Phil extends Thread { private Fork left; f0: Fork p0: Phil right private Fork right; left . . . left public void run( ) { p0: Phil f2: Fork while (true) { think(); left.get(this); right right.get(this); f1: Fork p1: Phil eat(); // using left & right left right right.put(this); left.put(this); } } . . . } Laser 2005 - Summer School on 11 Software Engineering
Example: Dining Philosophers in Java Class Fork { private boolean taken = false; . . . f0: Fork p2: Phil right synchronized void get(Phil p) { while (taken) wait (); left left taken = true; …println( p.toString() + p0: Phil f2: Fork “ picked up ” + toString()); } right synchronized void put(Phil p) { f1: Fork p1: Phil …println( p.toString() + “ put down ” + toString()); left right taken = false; notifyAll(); } . . . } Laser 2005 - Summer School on 12 Software Engineering
Overview of lecture series ♦ Background – Contracts – Multi-threaded OO programs – Concurrency problems ♦ Introduction to Szumo ♦ Case study ♦ Semantic and implementation details ♦ Related concurrency models ♦ Ongoing and future work Laser 2005 - Summer School on 13 Software Engineering
Problem: Interleaving of concurrency logic with “functional” logic Class Fork { Class Phil extends Thread { private boolean taken = false; private Fork left; . . . private Fork right; synchronized void put(Phil p) { . . . …println( p.toString() + public void run( ) { “ put down ” + while (true) { this.toString(); think(); taken = false; left.get(this); notifyAll(); right.get(this); } eat(); right.put(this); synchronized void get(Phil p) { left.put(this); while (taken) wait (); } taken = true; } …println( p.toString() + . . . “ picked up ” + } this.toString(); } Laser 2005 - Summer School on 14 Software Engineering
Problem: Undocumented synchronization rights and responsibilities ♦ Philosopher’s right / Fork’s responsibility: – A philosopher has exclusive access to a fork after calling “get” until the next call to “put” ♦ Philosopher’s responsibility / Fork’s right: – A philosopher alternates in first calling “get” and then “put” – A philosopher uses a fork only between a call to “get” and the next call to “put” Unstated correctness criteria produce brittle designs Laser 2005 - Summer School on 15 Software Engineering
Behavior contracts can express limited synchronization rights and responsibilities ♦ Here, only clients’ responsibilities / suppliers’ rights Class Fork { private Philosopher holder; synchronized void get(Phil p) . . . require (holder != p) synchronized void put(Phil p) { require (holder == p) while (holder != null) wait (); { holder = p; …println( p.toString() + …println( p.toString() + “ put down ” + “ picked up ” + this.toString(); this.toString(); holder = null; } notifyAll(); } ♦ Cannot express the mutual exclusion right / responsibility Laser 2005 - Summer School on 16 Software Engineering
Problem: Failure to “protect” critical regions ♦ E.g ., omit call(s) to “…get(…)” or omit f0: Fork p2: Phil right assignment to “taken” in left left “get” method p0: Phil f2: Fork ♦ Data race : uncoordinated access to shared data (in right this case, f 2 ) f1: Fork p1: Phil left right ♦ Data races are difficult to detect and isolate Laser 2005 - Summer School on 17 Software Engineering
Problem: Potential for starvation f0: Fork p2: Phil f0: Fork p2: Phil right right left left left left p0: Phil f2: Fork p0: Phil f2: Fork right right f1: Fork p1: Phil f1: Fork p1: Phil left right left right Laser 2005 - Summer School on 18 Software Engineering
Problem: Potential for deadlock ♦ Root cause: incrementally f0: Fork p2: Phil right acquiring multiple shared objects for some critical left left region p0: Phil f2: Fork ♦ Well-known solution: Impose an acquisition right order on the objects f1: Fork p1: Phil ♦ Requires: Global left right agreement on the acquisition order Laser 2005 - Summer School on 19 Software Engineering
Detour: Enforcing an acquisition order Class Phil extends Thread { . . . private Fork left; public void run( ) { private Fork right; while (true) { . . . think(); private void reserveTwo( ) { reserveTwo(); if (left < right) { left.get(this); left.reserve(); right.get(this); right.reserve(); eat(); } else { right.put(this); right.reserve(); left.put(this); left.reserve(); unreserveTwo(); } } } } private void unreserveTwo() { . . . left.unreserve(); } right.unreserve(); } Laser 2005 - Summer School on 20 Software Engineering
Detour: Enforcing an acquisition order Class Fork { . . . synchronized void reserve() { while (taken) wait (); taken = true; } synchronized void unreserve() { taken = false; notifyAll(); } synchronized void get(Phil p) { …println( p.toString() + “ picked up ” + toString() ); } synchronized void put(Phil p) { …println( p.toString() + “ put down ” + toString() ); } . . . } Laser 2005 - Summer School on 21 Software Engineering
Problem: Potential for deadlock The “ordered-acquisition solution” may not apply: ♦ If suppliers are not known a priori, but can change during execution ♦ If a client has indirect suppliers (transitive access dependences) c 0 ’s direct supplier, s 0 , c0: C c1: C should encapsulate its indirect supplier, s 1 ; similarly for c 1 Thus, c 0 acquires s 0 and s0: S s1: S then s 1 ; but c 1 acquires s 1 and then s 0 ! Laser 2005 - Summer School on 22 Software Engineering
Recommend
More recommend