-- NewFIFODriver.sak
-- last edited by Suzuki: 28-Nov-81 22:45:19 

DIRECTORY
  FIFO: TYPE, 
  SakuraRT: TYPE, 
  SimIO: TYPE;

NewFIFODriver: MONITOR
  IMPORTS FIFO, SakuraRT, SimIO
  
  = BEGIN
  Reader: PROC
       [DataAv: SakuraRT.Handle, DataOut: SakuraRT.Handle, ReadReq: SakuraRT.Handle] = {
    data: CARDINAL;
    {ENABLE {ABORTED => GO TO Aborted};
     SimIO.WF0["  Reader started.*n"]; 
     THROUGH [0..30) DO
         SakuraRT.Delay[20]; 
         WHILE NOT (SakuraRT.GetBool[DataAv] = TRUE) DO
           SakuraRT.StandardDelay[]
           ENDLOOP; 
         SakuraRT.Put[ReadReq, NEW[BOOLEAN ← TRUE]]; 
         data ← SakuraRT.GetCard[DataOut]; 
         SimIO.WF1["%u  ", @data]; 
         SakuraRT.Delay[10]; 
         SakuraRT.Put[ReadReq, NEW[BOOLEAN ← FALSE]]
         ENDLOOP; 
     SimIO.WF0["  Reader terminated.*n"]; 
     SakuraRT.ProcessEnd[]}
    EXITS
      Aborted => SakuraRT.Abort[]}; 
  
  Writer: PROC [SpaceAv: SakuraRT.Handle, 
                WriteReq: SakuraRT.Handle, 
                DataIn: SakuraRT.Handle] = {
    i: CARDINAL;
    {ENABLE {ABORTED => GO TO Aborted};
     SimIO.WF0[" Writer started.*n"]; 
     FOR i IN [0..30) DO
         SakuraRT.Delay[20]; 
         WHILE NOT (SakuraRT.GetBool[SpaceAv] = TRUE) DO
           SakuraRT.StandardDelay[]
           ENDLOOP; 
         SakuraRT.Put[DataIn, NEW[CARDINAL ← i]]; 
         SakuraRT.Put[WriteReq, NEW[BOOLEAN ← TRUE]]; 
         SimIO.WF1["%u-  ", @i]; 
         SakuraRT.Delay[10]; 
         SakuraRT.Put[WriteReq, NEW[BOOLEAN ← FALSE]]
         ENDLOOP; 
     SimIO.WF0[" Writer terminated.*n"]; 
     SakuraRT.ProcessEnd[]}
    EXITS
      Aborted => SakuraRT.Abort[]}; 
  
  Start: PROC [Init, ReadReq, WriteReq: SakuraRT.Handle] = {
    {ENABLE {ABORTED => GO TO Aborted};
     SakuraRT.Put[ReadReq, NEW[BOOLEAN ← FALSE]]; 
     SakuraRT.Put[WriteReq, NEW[BOOLEAN ← FALSE]]; 
     SakuraRT.Delay[10]; 
     SakuraRT.Put[Init, NEW[BOOLEAN ← TRUE]]; 
     SakuraRT.Delay[5]; 
     SakuraRT.Put[Init, NEW[BOOLEAN ← FALSE]]; 
     SakuraRT.ProcessEnd[]}
    EXITS
      Aborted => SakuraRT.Abort[]};
  
  SimIO.Start[]; 
  {init: SakuraRT.Handle ← SakuraRT.Create[]; 
   write: SakuraRT.Handle ← SakuraRT.Create[]; 
   read: SakuraRT.Handle ← SakuraRT.Create[]; 
   in: SakuraRT.Handle ← SakuraRT.Create[]; 
   space: SakuraRT.Handle ← SakuraRT.Create[]; 
   data: SakuraRT.Handle ← SakuraRT.Create[]; 
   out: SakuraRT.Handle ← SakuraRT.Create[]; 
   fifo, reader, writer, start: PROCESS; 
   SakuraRT.IncCurrent[];
   fifo ← FORK FIFO.FIFOFunc[size: 100, 
                             Init: init, 
                             WriteRequest: write, 
                             ReadRequest: read, 
                             DIn: in, 
                             SpaceAv: space, 
                             DataAv: data, 
                             DOut: out];SakuraRT.CatalogProcId[fifo]; 
   SakuraRT.IncCurrent[];
   reader ← FORK Reader[DataAv: data, DataOut: out, ReadReq: read];
   SakuraRT.CatalogProcId[reader]; 
   SakuraRT.IncCurrent[];
   writer ← FORK Writer[SpaceAv: space, WriteReq: write, DataIn: in];
   SakuraRT.CatalogProcId[writer]; 
   SakuraRT.IncCurrent[];
   start ← FORK Start[Init: init, ReadReq: read, WriteReq: write];
   SakuraRT.CatalogProcId[start]; 
   SakuraRT.DecCurrent[]; 
   SakuraRT.Join[fifo]; 
   SakuraRT.Join[reader]; 
   SakuraRT.Join[writer]; 
   SakuraRT.Join[start]; 
   SakuraRT.IncCurrent[]}; 
  SimIO.Stop[]
  END.