-- File: [Indigo]<Sakura>Dragon>DragonArbiterImpl1.sak
-- 15-Mar-82  9:19:33

DIRECTORY
  DragonArbiter1: TYPE, 
  SakuraRT: TYPE;

DragonArbiterImpl1: MONITOR
  IMPORTS SakuraRT
  EXPORTS DragonArbiter1
  
  = BEGIN
  Arbiter: PUBLIC PROC [ClockA, ClockB, Proc1Rq, Proc2Rq: SakuraRT.Handle, 
                        Proc1Gr, Proc2Gr: SakuraRT.Handle] = {
    granted: BOOLEAN ← FALSE; 
    last: CARDINAL ← 0; 
    Grant: ENTRY PROC = {
      IF last = 1 
         THEN IF NARROW[SakuraRT.Get[Proc1Rq], REF BOOLEAN]↑ AND granted 
                 THEN RETURN 
                 ELSE IF NARROW[SakuraRT.Get[Proc2Rq], REF BOOLEAN]↑ 
                         THEN {SakuraRT.Put[Proc1Gr, NEW[BOOLEAN ← FALSE]]; 
                               last ← 2; SakuraRT.Put[Proc2Gr, NEW[BOOLEAN ← TRUE]]; 
                               granted ← TRUE} 
                         ELSE IF NARROW[SakuraRT.Get[Proc1Rq], REF BOOLEAN]↑ 
                                 THEN {SakuraRT.Put[Proc1Gr, NEW[BOOLEAN ← TRUE]]; 
                                       granted ← TRUE} 
                                 ELSE {SakuraRT.Put[Proc1Gr, NEW[BOOLEAN ← FALSE]]; 
                                       granted ← FALSE} 
         ELSE IF last = 2 
                 THEN IF NARROW[SakuraRT.Get[Proc2Rq], REF BOOLEAN]↑ AND granted 
                         THEN RETURN 
                         ELSE IF NARROW[SakuraRT.Get[Proc1Rq], REF BOOLEAN]↑ 
                                 THEN {SakuraRT.Put[Proc2Gr, NEW[BOOLEAN ← FALSE]]; 
                                       last ← 1; 
                                       SakuraRT.Put[Proc1Gr, NEW[BOOLEAN ← TRUE]]; 
                                       granted ← TRUE} 
                                 ELSE IF NARROW[SakuraRT.Get[Proc2Rq], REF BOOLEAN]↑ 
                                         THEN {SakuraRT.Put[Proc2Gr, NEW[BOOLEAN ← TRUE]]; 
                                               granted ← TRUE} 
                                         ELSE {SakuraRT.Put[Proc2Gr, NEW[BOOLEAN ← FALSE]]; 
                                               granted ← FALSE} 
                 ELSE IF NARROW[SakuraRT.Get[Proc1Rq], REF BOOLEAN]↑ 
                         THEN {last ← 1; SakuraRT.Put[Proc1Gr, NEW[BOOLEAN ← TRUE]]; 
                               granted ← TRUE} 
                         ELSE IF NARROW[SakuraRT.Get[Proc2Rq], REF BOOLEAN]↑ THEN 
                                 {last ← 2; SakuraRT.Put[Proc2Gr, NEW[BOOLEAN ← TRUE]]; 
                                  granted ← TRUE}}; -- Grant
    {ENABLE {ABORTED => GO TO Aborted};
     DO SakuraRT.GetNew[ClockB, TRUE]; Grant[]
        ENDLOOP; 
     SakuraRT.ProcessEnd[]}
    EXITS
      Aborted => SakuraRT.Abort[]};
  
  END.