-- NewFIFOImpl.sak -- last edited by Suzuki: 20-Apr-82 12:55:47 DIRECTORY FIFO: TYPE, SakuraRT: TYPE; NewFIFOImpl: MONITOR IMPORTS SakuraRT EXPORTS FIFO = BEGIN choice1: SakuraRT.Choice _ SakuraRT.CreateChoice[]; FIFOFunc: PUBLIC PROC [size: CARDINAL, Init, WriteRequest, ReadRequest: SakuraRT.Handle, DIn: SakuraRT.Handle, SpaceAv, DataAv: SakuraRT.Handle, DOut: SakuraRT.Handle] = { guardian: PROC = { {ENABLE {ABORTED => GO TO Aborted}; Initialized: BOOLEAN _ FALSE; SakuraRT.RegisterUp[choice1, 1, Init]; SakuraRT.RegisterUp[choice1, 2, ReadRequest]; SakuraRT.RegisterUp[choice1, 3, WriteRequest]; DO SELECT SakuraRT.GetChoice[choice1] FROM 1 => {IF SakuraRT.GetBool[ReadRequest] OR SakuraRT.GetBool[WriteRequest] THEN ERROR; Initialized _ TRUE}; 2 => IF NOT Initialized OR SakuraRT.GetBool[Init] OR NOT SakuraRT.GetBool[DataAv] THEN ERROR; 3 => IF NOT Initialized OR SakuraRT.GetBool[Init] OR NOT SakuraRT.GetBool[SpaceAv] THEN ERROR ENDCASE => ERROR ENDLOOP; SakuraRT.ProcessEnd[]} EXITS Aborted => SakuraRT.Abort[]}; p: PROCESS; {ENABLE {ABORTED => GO TO Aborted}; p _ SakuraRT.Fork[guardian]; SakuraRT.CatalogProcId[p]; {A: ARRAY INTEGER [0..37] OF CARDINAL; rp, wp: CARDINAL; DO SakuraRT.GetNew[Init, TRUE]; {rp _ 1; wp _ 0; SakuraRT.Put[SpaceAv, NEW[BOOLEAN _ TRUE]]; SakuraRT.Put[DataAv, NEW[BOOLEAN _ FALSE]]}; {st1: PROC = { {ENABLE {ABORTED => GO TO Aborted}; {DO SakuraRT.GetNew[ReadRequest, TRUE]; {SakuraRT.Delay[1]; SakuraRT.Put[DataAv, NEW[BOOLEAN _ FALSE]]; rp _ rp + 1; SakuraRT.Put[DOut, NEW[CARDINAL _ A[rp]]]; SakuraRT.Put[SpaceAv, NEW [BOOLEAN _ NOT SakuraRT.GetBool[WriteRequest] AND wp < rp + size]]}; SakuraRT.GetNew[ReadRequest, FALSE]; SakuraRT.Put[DataAv, NEW[BOOLEAN _ rp <= wp]] ENDLOOP; SakuraRT.ProcessEnd[]}} EXITS Aborted => SakuraRT.Abort[]}; st2: PROC = { {ENABLE {ABORTED => GO TO Aborted}; {DO SakuraRT.GetNew[WriteRequest, TRUE]; {SakuraRT.Delay[1]; SakuraRT.Put[SpaceAv, NEW[BOOLEAN _ FALSE]]; wp _ wp + 1; A[wp] _ SakuraRT.GetCard[DIn]; SakuraRT.Put[DOut, NEW[CARDINAL _ A[rp]]]; SakuraRT.Put[DataAv, NEW [BOOLEAN _ NOT SakuraRT.GetBool[ReadRequest] AND rp <= wp]]}; SakuraRT.GetNew[WriteRequest, FALSE]; SakuraRT.Put[SpaceAv, NEW[BOOLEAN _ wp < rp + size]] ENDLOOP; SakuraRT.ProcessEnd[]}} EXITS Aborted => SakuraRT.Abort[]}; process1, process2: PROCESS; process1 _ SakuraRT.Fork[st1]; SakuraRT.CatalogProcId[process1]; process2 _ SakuraRT.Fork[st2]; SakuraRT.CatalogProcId[process2]; SakuraRT.DecCurrent[]; [] _ SakuraRT.Join[process1]; [] _ SakuraRT.Join[process2]; SakuraRT.IncCurrent[]} ENDLOOP}; [] _ SakuraRT.Join[p]; SakuraRT.ProcessEnd[]} EXITS Aborted => SakuraRT.Abort[]}; NULL END.