-- FIFODriver.sak
-- last edited by Suzuki: 20-Nov-81 12:47:25 

DIRECTORY
  FIFO: TYPE, 
  Connector: TYPE, 
  Process: TYPE,
  Scheduler: TYPE, 
  SimIO: TYPE;

FIFODriver: MONITOR
  IMPORTS Connector, FIFO, Process, Scheduler, SimIO
  
  = BEGIN
  Reader: PROC
       [DataAv: Connector.Handle, DataOut: Connector.Handle, ReadReq: Connector.Handle] = {
    {Scheduler.IncCurrent[];
    Process.Yield[];
    SimIO.WF0["  Reader started.*n"]; 
     THROUGH [0..50) DO
         Scheduler.Delay[10]; 
         WHILE NOT (NARROW[Connector.Get[DataAv], REF BOOLEAN]↑ = TRUE) DO
           Scheduler.StandardDelay[]
           ENDLOOP; 
         Connector.Put[ReadReq, NEW[BOOLEAN ← TRUE]]; 
         SimIO.WF1["%u  ", NARROW[Connector.Get[DataOut], REF CARDINAL]↑]; 
         Scheduler.Delay[5]; 
         Connector.Put[ReadReq, NEW[BOOLEAN ← FALSE]]
         ENDLOOP; 
     SimIO.WF0["  Reader terminated.*n"]; 
     Scheduler.ProcessEnd[]}; 
    }; 
  
  Writer: PROC [SpaceAv: Connector.Handle, 
                WriteReq: Connector.Handle, 
                DataIn: Connector.Handle] = {
    {i: CARDINAL; 
     Scheduler.IncCurrent[];
    Process.Yield[];
    SimIO.WF0[" Writer started.*n"]; 
     FOR i IN [0..50) DO
         Scheduler.Delay[10]; 
         WHILE NOT (NARROW[Connector.Get[SpaceAv], REF BOOLEAN]↑ = TRUE) DO
           Scheduler.StandardDelay[]
           ENDLOOP; 
         Connector.Put[DataIn, NEW[CARDINAL ← i]]; 
         Connector.Put[WriteReq, NEW[BOOLEAN ← TRUE]]; 
         SimIO.WF1["%u-  ", i]; 
         Scheduler.Delay[5]; 
         Connector.Put[WriteReq, NEW[BOOLEAN ← FALSE]]
         ENDLOOP; 
     SimIO.WF0[" Writer terminated.*n"]; 
     Scheduler.ProcessEnd[]}; 
    }; 
  
  Start: PROC [Init, ReadReq, WriteReq: Connector.Handle] = {
    {Scheduler.IncCurrent[];
     Process.Yield[];
     Connector.Put[ReadReq, NEW[BOOLEAN ← FALSE]]; 
     Connector.Put[WriteReq, NEW[BOOLEAN ← FALSE]]; 
     Scheduler.Delay[10]; 
     Connector.Put[Init, NEW[BOOLEAN ← TRUE]]; 
     Scheduler.Delay[5]; 
     Connector.Put[Init, NEW[BOOLEAN ← FALSE]]; 
     Scheduler.ProcessEnd[]}; 
    };
  
  SimIO.Start["FIFO.jam"]; 
  {init: Connector.Handle ← Connector.Create[]; 
   write: Connector.Handle ← Connector.Create[]; 
   read: Connector.Handle ← Connector.Create[]; 
   in: Connector.Handle ← Connector.Create[]; 
   space: Connector.Handle ← Connector.Create[]; 
   data: Connector.Handle ← Connector.Create[]; 
   out: Connector.Handle ← Connector.Create[]; 
   fifo: PROCESS ← FORK FIFO.FIFOFunc[size: 100, 
                                      Init: init, 
                                      WriteRequest: write, 
                                      ReadRequest: read, 
                                      DIn: in, 
                                      SpaceAv: space, 
                                      DataAv: data, 
                                      DOut: out]; 
   reader: PROCESS ← FORK Reader[DataAv: data, DataOut: out, ReadReq: read]; 
   writer: PROCESS ← FORK Writer[SpaceAv: space, WriteReq: write, DataIn: in]; 
   start: PROCESS ← FORK Start[Init: init, ReadReq: read, WriteReq: write]; 
   [] ← Scheduler.Join[fifo]; [] ← Scheduler.Join[reader]; 
   [] ← Scheduler.Join[writer]; [] ← Scheduler.Join[start]}; 
  SimIO.Stop[]
  END.