310 likes | 388 Views
Advanced Topics in Object Technology. Bertrand Meyer. Lecture 26: Concurrent O-O principles. Design by Contract. class BOUNDED_QUEUE [ G ] feature put ( x : G ) is -- Add x to queue. require not is_full do … ensure not is_empty end remove : G is
E N D
Advanced Topics in Object Technology Bertrand Meyer ATOT - Lecture 26, 30 June 2003
Lecture 26: Concurrent O-O principles ATOT - Lecture 26, 30 June 2003
Design by Contract classBOUNDED_QUEUE [G] feature put (x: G) is -- Add x to queue. require notis_full do … ensure notis_empty end remove: Gis -- Delete oldest element from queue. require notis_empty do … ensure notis_full end ATOT - Lecture 26, 30 June 2003
The contract model (cont’d) invariant maxcount = capacity – 1 0 <= oldest oldest <= capacity 0 <= next next <= capacity abs (next – oldest) < capacity end oldest 1 capacity maxcount next ATOT - Lecture 26, 30 June 2003
The contract of a feature Obligations Benefits (Satisfy precondition:) Make sure queue not full. (From postcondition:) Make queue not empty, x added. Client (Satisfy postcondition:) Insert x, making sure queue is not empty. (From precondition:) Simpler processing thanks to assumption that queue not full. Supplier ATOT - Lecture 26, 30 June 2003
The correctness of a class createa.make (…) • (1-n) For every exported routine r: {INV and prer} dor {INV and postr} • (1-m) For every creation procedure cp: {precp} docp {postcp and INV} S1 a.f (…) S2 a.g (…) S3 a.f (…) S4 ATOT - Lecture 26, 30 June 2003
Express messages? • An express message is a message that must be treated right away, interrupting any current routine call. • But: how do we preserve the consistency of objects (invariants)? • The model will support a restricted form of express messages, which does not conflict with provability. • Unit of granularity for mutual exclusion is routine call. • But: can be interrupted, causing an exception. ATOT - Lecture 26, 30 June 2003
Provability • Proof rule for routines: { INV p } Body (r) { INV q } p Pre (r) q Post (r) { p’ } Call (r) { q’ } p Pre (r) q Post (r) • In other words: to prove the validity of all calls, it suffices to prove (once!) the correctness of the body. ATOT - Lecture 26, 30 June 2003
What becomes of the contract model? q: BOUNDED_QUEUE [X] a: X...if notq.is_fullthenq.put (a) end Or: q.removeq.put (x) • But: this does not work for separate threads of control! • What do preconditions now mean? ATOT - Lecture 26, 30 June 2003
Reserving an object q: separateBOUNDED_QUEUE [X] a: X...a := q.item... Other instructions (not calling remove) ...q.remove • How do we guarantee that item and remove apply to the same buffer element? • Proposed answer: Just use encapsulation. Argument passing serves as reservation. If object busy (processor not available), block object; processor will service other object if possible. ATOT - Lecture 26, 30 June 2003
Reserving an object (cont’d) classBUFFER_ACCESS [X] featureput (q: separateBOUNDED_QUEUE [G]; x: G) is-- Insert x into q, waiting if necessary -- until there is room.requirenotq.is_fulldoq.put (x)ensure notq.is_emptyend ATOT - Lecture 26, 30 June 2003
Reserving an object (cont’d) remove (q: separateBOUNDED_QUEUE [G]) is-- Remove an element from q, waiting if -- necessary until there is such an element.requirenotq.is_emptydoq.removeensure notq.is_fullenditem (q: separateBOUNDED_QUEUE [G]): Gis-- Oldest element not yet consumed ... Left to reader ... end ATOT - Lecture 26, 30 June 2003
Semantic rules • With the class as shown on the previous pages, the call put (q) • will block until: • q is available. • The precondition notq.is_full is true. • The new rule only affects: • Separate arguments. • Precondition clauses which include calls on separate targets (i.e. x.f withxseparate). ATOT - Lecture 26, 30 June 2003
The original proof rule { INV p } Body (r) { INV q } p Pre (r) q Post (r) { p’ } Call (r) { q’ } p Pre (r) q Post (r) ATOT - Lecture 26, 30 June 2003
The new proof rule { INV p } Body (r) { INV q } p Nonsep_Pre (r) q Nonsep_Post (r) { p’ } Call (r) { q’ } p Nonsep_Pre (r) q Nonsep_Post (r) • Nonsep_pre (r): set of clauses in r’s precondition which do not involve any separate calls. • Similarly for Nonsep_post (r). ATOT - Lecture 26, 30 June 2003
Wait by necessity r (...; t: separateSOME_TYPE; ...) isdo ...t.f (...)other_instructionsend • When do we wait? ATOT - Lecture 26, 30 June 2003
Wait by necessity (cont’d) • For example: r (...; t: separateSOME_TYPE; ...) isdo ...t.p (...)other_instruction_1 ... other_instruction_n k:=t.some_valueend • Wait on queries (calls to attributes and functions), not procedure calls. WAIT HERE ATOT - Lecture 26, 30 June 2003
Blocking semantics is not always appropriate f: FILE ... iff /= Voidand thenf.readablethenf.some_input_routine --some_input_routineis any routine -- that reads data from the file; -- its precondition is readable.end ATOT - Lecture 26, 30 June 2003
Duels • Request immediate service: immediate_service • Accept immediate service: yield Challenger Holder normal_service immediate_service insist Challenger waits Exception in challenger Exception in holder; serve challenger. yield Challenger waits ATOT - Lecture 26, 30 June 2003
Dining philosophers ATOT - Lecture 26, 30 June 2003
Dining philosophers (cont’d) separate classPHILOSOPHER inheritPROCESSrename setupasgetup end create make feature {BUTLER}stepis dothink eat (left, right) end ATOT - Lecture 26, 30 June 2003
Dining philosophers (cont’d) feature {NONE}left, right: separateFORK -- The two required forks getupis-- Take any necessary initialization action.do ... endthinkis-- Any appropriate action.do ... endeat (l, r: separateFORK) is-- Eat, having grabbed l and r.do ... end end ATOT - Lecture 26, 30 June 2003
A binary tree class, non-parallel classBINARY_TREE [G] feature left, right: BINARY_TREE [G] nodes: INTEGERis -- Number of nodes in this tree do Result := node_count (left) + node_count (right) + 1 end feature {NONE} node_count (b: BINARY_TREE [G]): INTEGERis -- Number of nodes in b do ifb /= Voidthen Result := b.nodes end end end ATOT - Lecture 26, 30 June 2003
A binary tree class: Parallel version separate classBINARY_TREE [G] feature left, right: BINARY_TREE [G] … Other features … nodes: INTEGER update_nodesis -- Update nodes to reflect number of nodes in this -- tree. do nodes := 1 compute_nodes (left) compute_nodes (right) adjust_nodes (left) adjust_nodes (right) end ATOT - Lecture 26, 30 June 2003
Parallel version (cont’d) feature {NONE} compute_nodes (b: BINARY_TREE [G]) is -- Update information about the number of nodes in b. do ifb /= Voidthen b.update_nodes end end adjust_nodes (b: BINARY_TREE [G]) is -- Adjust number of nodes from those in b. do ifb /= Voidthen nodes := nodes + b.nodes end end end ATOT - Lecture 26, 30 June 2003
Other examples in OOSC-2 • Coroutines • Locking a resource — semaphores • An elevator control system • A watchdog mechanism (execute an action, but take control back if not done after t seconds) ATOT - Lecture 26, 30 June 2003
Two-level architecture SCOOP .NET THREADS … ATOT - Lecture 26, 30 June 2003
.NET remoting library • Provides a good basis for SCOOP: • AppDomains: Partition object set • Marshal by Value, Marshal by Reference • All types are potentially remotable • Threading library ATOT - Lecture 26, 30 June 2003
AppDomains Process AppDomain AppDomain O1 name “Almaviva” Context landlord loved_one O3 O2 “Figaro” “Susanna” Context ATOT - Lecture 26, 30 June 2003
Challenges • Conceptual: • Systematic approach to deadlock prevention • Precise fairness policies • Proof rules, actual proofs. • Organizational: • Language & compiler integrationBut also an opportunity • Building industrial-grade software in a universityBut: ETH CS tradition; Dept and university support ATOT - Lecture 26, 30 June 2003
End of lecture 26 ATOT - Lecture 26, 30 June 2003