-- 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.