-- from john -- I modified WorkLock to be a task, and not a protected type -- list modeled -- inlined -- no process of results ---------------------------------------------------------------------- type Work_Type is (o,d1,d2); type List_Type is (some,d1,d2,d1d2,d2d1); procedure Insert(work : in out List_Type; item : in Work_Type) is begin if work = some and item=d1 then work:=d1;return; end if; if work = some and item=d2 then work:=d2;return; end if; if item=d1 and work=d2 then work:=d2d1;return; end if; if item=d2 and work=d1 then work:=d1d2;return; end if; end Insert; procedure Remove(work : in out List_Type; item : out Work_Type) is begin item:=o; if work = d1 and ... then item:=d1; work:=some; return; end if; if work = d2 and ... then item:=d2; work:=some; return; end if; if work = d1d2 and ... then item:=d1; work:=d2; return; end if; if work = d2d1 and ... then item:=d2; work:=d1; return; end if; end Remove; ---------------------------------------------------------------------- task ASActivePool is entry StartUp; entry ShutDown; entry Get(item: out Work_Type; done : out Boolean); entry Put(item: in Work_Type); entry Finished; entry Execute; entry Complete; end ASActivePool; ---------------------------------------------------------------------- task AS1ActiveWorker is entry StartUp; entry ShutDown; entry Execute; end AS1ActiveWorker; task AS2ActiveWorker is entry StartUp; entry ShutDown; entry Execute; end AS2ActiveWorker; task AS3ActiveWorker is entry StartUp; entry ShutDown; entry Execute; end AS3ActiveWorker; task main; ---------------------------------------------------------------------- task body ASActivePool is executeDone : Boolean := TRUE; work : List_Type; begin -- accept ASinit; accept StartUp; work:=some; -- WorkPool.Create(work); Outer: loop loop select accept ShutDown; exit Outer; or accept Finished; accept Shutdown; exit Outer; or accept Put(item: in Work_Type) do if item = d1 then internal "callInsertd1"; end if; if item = d2 then internal "callInsertd2"; end if; Insert(work,item); if item = d1 then internal "returnInsertd1"; internal "returnInputd1"; end if; if item = d2 then internal "returnInsertd2"; internal "returnInputd2"; end if; end Put; or accept Execute; AS1ActiveWorker.Execute; AS2ActiveWorker.Execute; AS3ActiveWorker.Execute; exit; end select; end loop; executeDone := FALSE; loop select when ... or executeDone => accept Get(item: out Work_Type; done : out Boolean) do if executeDone then done := TRUE; else done := FALSE; Remove(work,item); end if; end Get; or accept Put(item: in Work_Type) do if item = d1 then internal "callInsertd1"; end if; if item = d2 then internal "callInsertd2"; end if; Insert(work,item); if item = d1 then internal "returnInsertd1"; internal "returnInputd1"; end if; if item = d2 then internal "returnInsertd2"; internal "returnInputd2"; end if; end Put; or accept Finished; executeDone := TRUE; end select; if ... then executeDone := TRUE; end if; exit when ...; end loop; accept Complete; end loop Outer; end ASActivePool; ---------------------------------------------------------------------- task body AS1ActiveWorker is done : Boolean; choice_m : range 1 .. 6 :=6; item: Work_Type; begin accept StartUp; loop select accept ShutDown; exit; or accept Execute; end select; -- Repeatedly get work, process it, put new work loop ASActivePool.Get(item,done); exit when done; -- Perform the work if item = d1 then internal "calldoWorkd1"; end if; if item = d2 then internal "calldoWorkd2"; end if; loop choice_m:=...; case choice_m is when 1 => -- Create; ASActivePool.StartUp; -- AS1ActiveWorker.Startup; error AS2ActiveWorker.Startup; AS3ActiveWorker.Startup; when 2 => -- Input; ASActivePool.Put(...); when 3 => -- Execute; ASActivePool.Execute; ASActivePool.Complete; when 4 => -- Destroy; ASActivePool.Finished; -- AS1ActiveWorker.ShutDown; error AS2ActiveWorker.ShutDown; AS3ActiveWorker.ShutDown; ASActivePool.ShutDown; when 5 => null; when 6 => exit; end case; end loop; choice_m:=6; -- reset done := ...; if item = d1 then internal "returndoWorkd1"; end if; if item = d2 then internal "returndoWorkd2"; end if; item:=...; -- Short-circuit the computation if indicated if done then ASActivePool.Finished; exit; end if; -- Put the new work back ASActivePool.Put(item); item:=o;--reset end loop; end loop; end AS1ActiveWorker; ---------------------------------------------------------------------- task body AS2ActiveWorker is done : Boolean; choice_m : range 1 .. 6:=6; item: Work_Type; begin accept StartUp; loop select accept ShutDown; exit; or accept Execute; end select; -- Repeatedly get work, process it, put new work loop ASActivePool.Get(item,done); exit when done; if item = d1 then internal "calldoWorkd1"; end if; if item = d2 then internal "calldoWorkd2"; end if; loop -- nondeterministic choice choice_m:=...; case choice_m is when 1 => -- Create; ASActivePool.StartUp; AS1ActiveWorker.Startup; --AS2ActiveWorker.Startup; AS3ActiveWorker.Startup; when 2 => -- Input; ASActivePool.Put(...); when 3 => -- Execute; ASActivePool.Execute; ASActivePool.Complete; when 4 => -- Destroy; ASActivePool.Finished; AS1ActiveWorker.ShutDown; --AS2ActiveWorker.ShutDown; AS3ActiveWorker.ShutDown; ASActivePool.ShutDown; when 5 => null; when 6 => exit; end case; end loop; choice_m:=6; -- reset done:=...; if item = d1 then internal "returndoWorkd1"; end if; if item = d2 then internal "returndoWorkd2"; end if; item:=...; -- Short-circuit the computation if indicated if done then ASActivePool.Finished; exit; end if; -- Put the new work back ASActivePool.Put(item); item:=o;--reset end loop; end loop; end AS2ActiveWorker; ---------------------------------------------------------------------- task body AS3ActiveWorker is done : Boolean; choice_m : range 1 .. 6 :=6; item: Work_Type; begin accept StartUp; loop select accept ShutDown; exit; or accept Execute; end select; -- Repeatedly get work, process it, put new work loop -- Attempt to get new work ASActivePool.Get(item,done); exit when done; -- Perform the work if item = d1 then internal "calldoWorkd1"; end if; if item = d2 then internal "calldoWorkd2"; end if; loop choice_m:=...; -- nondeterministic choice case choice_m is when 1 => -- Create; ASActivePool.StartUp; AS1ActiveWorker.Startup; AS2ActiveWorker.Startup; --AS3ActiveWorker.Startup; when 2 => -- Input; ASActivePool.Put(...); when 3 => -- Execute; ASActivePool.Execute; ASActivePool.Complete; when 4 => -- Destroy; ASActivePool.Finished; AS1ActiveWorker.ShutDown; AS2ActiveWorker.ShutDown; --AS3ActiveWorker.ShutDown; ASActivePool.ShutDown; when 5 => null; when 6 => exit; end case; end loop; choice_m:=6; -- reset done:=...; if item = d1 then internal "returndoWorkd1"; end if; if item = d2 then internal "returndoWorkd2"; end if; item:=...; --end work if done then ASActivePool.Finished; exit; end if; -- Put the new work back ASActivePool.Put(item); item:=o; end loop; end loop; end AS3ActiveWorker; ---------------------------------------------------------------------- -- we add here the stub task body main is choice_m : range 1 .. 6:=6; item: Work_Type; begin loop -- nondeterministic choice choice_m:=...; case choice_m is when 1 => -- Create; ASActivePool.StartUp; AS1ActiveWorker.Startup; AS2ActiveWorker.Startup; AS3ActiveWorker.Startup; when 2 => -- Input; ASActivePool.Put(...); when 3 => -- Execute; ASActivePool.Execute; ASActivePool.Complete; when 4 => -- Destroy; ASActivePool.Finished; AS1ActiveWorker.ShutDown; AS2ActiveWorker.ShutDown; AS3ActiveWorker.ShutDown; ASActivePool.ShutDown; when 5 => null; when 6 => exit; end case; end loop; choice_m:=6; -- reset end main;