-- ProcessOps.Mesa  Edited by Sandman on June 30, 1980  11:51 AM
-- Copyright  Xerox Corporation 1979, 1980

DIRECTORY
  ControlDefs USING [FrameHandle, SVPointer, WDCreg],
  Mopcodes USING [
    zBCAST, zDWDC, zME, zMRE, zMXD, zMXW, zNOTIFY, zREQUEUE, zRR, zWR],
  ProcessDefs USING [DisableInterrupts, Priority],
  PSBDefs USING [ProcessHandle];

ProcessOps: DEFINITIONS IMPORTS ProcessDefs =
  BEGIN OPEN PSBDefs;

  CurrentPSB: POINTER TO ProcessHandle = LOOPHOLE[21B];
  ReadyList: QueueHandle = LOOPHOLE[22B];
  CurrentState: POINTER TO ControlDefs.SVPointer = LOOPHOLE[23B];

  FirstProcess: POINTER TO ProcessHandle = LOOPHOLE[1075B];
  LastProcess: POINTER TO ProcessHandle = LOOPHOLE[1076B];
  FirstStateVector: POINTER TO ControlDefs.SVPointer = LOOPHOLE[1077B];

  WakeupsWaiting: POINTER TO WORD = LOOPHOLE[452B];
  ActiveWord: POINTER TO WORD = LOOPHOLE[453B];

  Fork: PROCEDURE [UNSPECIFIED] RETURNS [ProcessHandle];
  Join: PROCEDURE [ProcessHandle] RETURNS [ControlDefs.FrameHandle];
  TimerGrain: CARDINAL = 50; -- 50 milliseconds/tick

  Clean: ProcessHandle = LOOPHOLE[0];

  NullQueueHandle: QueueHandle = LOOPHOLE[0];
  QueueHandle: TYPE = POINTER TO Queue;
  Queue: TYPE = ProcessHandle;

  Enter: PROCEDURE [POINTER TO MONITORLOCK] RETURNS [success: BOOLEAN] = MACHINE
    CODE BEGIN Mopcodes.zME END;

  Exit: PROCEDURE [POINTER TO MONITORLOCK] = MACHINE CODE BEGIN Mopcodes.zMXD END;

  Wait: PROCEDURE [POINTER TO MONITORLOCK, POINTER TO CONDITION, CARDINAL] =
    MACHINE CODE BEGIN Mopcodes.zMXW END;

  ReEnter: PROCEDURE [POINTER TO MONITORLOCK, POINTER TO CONDITION]
    RETURNS [success: BOOLEAN] = MACHINE CODE BEGIN Mopcodes.zMRE END;

  Notify: PROCEDURE [POINTER TO CONDITION] = MACHINE CODE
    BEGIN Mopcodes.zNOTIFY END;

  Broadcast: PROCEDURE [POINTER TO CONDITION] = MACHINE CODE
    BEGIN Mopcodes.zBCAST END;

  Requeue: PROCEDURE [from: QueueHandle, to: QueueHandle, p: ProcessHandle] =
    MACHINE CODE BEGIN Mopcodes.zREQUEUE END;

  -- Note: this depends on having one instruction after enabling:

  EnableAndRequeue: PROCEDURE [QueueHandle, QueueHandle, ProcessHandle] = MACHINE
    CODE BEGIN Mopcodes.zDWDC; Mopcodes.zREQUEUE END;

  ReadWDC: PROCEDURE RETURNS [CARDINAL] = MACHINE CODE
    BEGIN Mopcodes.zRR, ControlDefs.WDCreg END;

  WriteWDC: PROCEDURE [CARDINAL] = MACHINE CODE
    BEGIN Mopcodes.zWR, ControlDefs.WDCreg END;

  ISetPriority: PUBLIC PROCEDURE [p: ProcessDefs.Priority] = INLINE
    BEGIN
    ProcessDefs.DisableInterrupts[];
    CurrentPSB.priority ← p;
    EnableAndRequeue[ReadyList, ReadyList, CurrentPSB↑];
    END;


  END.