-- RTProcessImpl.Mesa
-- last edited September 9, 1982 9:34 am by Paul Rovner
DIRECTORY
CPSwapDefs USING[ProcessState],
PSB USING[PsbIndex, PsbNull, PDA, PsbHandle],
RTOS USING[RTProcessStarted, GetCurrent],
RTProcess USING[GetPSBIPageFaults],
RTProcessPrivate USING[ProcessObject, MapRecord, InvalidateFaultingCedarProcess],
SafeStorage USING[NewZone];
RTProcessImpl: MONITOR -- protects MapPSBIToHandle
IMPORTS RTOS, RTProcess, RTProcessPrivate, SafeStorage
EXPORTS RTProcess, RTProcessPrivate
= BEGIN OPEN RTProcess, RTProcessPrivate;
-- types
Handle: TYPE = REF Object;
Object: PUBLIC TYPE = RTProcessPrivate.ProcessObject;
-- variables
processZone: ZONE = SafeStorage.NewZone[quantized];
MapPSBIToHandle: PUBLIC REF MapRecord;
-- SIGNALs
InvalidProcess: PUBLIC ERROR[h: Handle] = CODE;
-- PROCs
Current: PUBLIC PROC RETURNS[Handle] = {RETURN[MapPSBIToHandle[RTOS.GetCurrent[]]]};
PSBIToHandle: PUBLIC PROC[psbi: PSB.PsbIndex] RETURNS[Handle] =
{RETURN[MapPSBIToHandle[psbi]]};
HandleToPSBI: PUBLIC PROC[h: Handle] RETURNS[PSB.PsbIndex] =
{IF NOT Valid[h] THEN ERROR InvalidProcess[h];
RETURN[h.psbi]};
EnumerateCedarProcesses: PUBLIC PROC[p: PROC[Handle]
RETURNS[stop: BOOLEAN]]
RETURNS[stopped: BOOLEAN] =
{FOR h: Handle ← FirstHandle[], NextHandle[h] UNTIL h = NIL
DO IF Valid[h] AND p[h] THEN RETURN[TRUE]
ENDLOOP;
RETURN[FALSE]};
FirstHandle: ENTRY PROC RETURNS[Handle] =
{ENABLE UNWIND => NULL;
FOR psbi: PSB.PsbIndex IN PSB.PsbIndex
DO handle: Handle = MapPSBIToHandle[psbi];
IF DoValid[handle] THEN RETURN[handle];
ENDLOOP;
RETURN[NIL]};
NextHandle: ENTRY PROC[h: Handle] RETURNS[Handle] =
{ENABLE UNWIND => NULL;
FOR psbi: PSB.PsbIndex IN [h.psbi+1..LAST[PSB.PsbIndex]]
DO handle: Handle = MapPSBIToHandle[psbi];
IF DoValid[handle] THEN RETURN[handle];
ENDLOOP;
RETURN[NIL]};
PageFaults: PUBLIC PROC[h: Handle] RETURNS[LONG INTEGER] =
{RETURN[RTProcess.GetPSBIPageFaults[HandleToPSBI[h ! InvalidProcess => GOTO forgetIt]]];
EXITS forgetIt => RETURN[0]};
-- escape hatch
SetAttachment: PUBLIC ENTRY PROC[h: Handle, attachment: REF ANY] =
{ENABLE UNWIND => NULL;
IF NOT Valid[h] THEN ERROR InvalidProcess[h];
h.attachment ← attachment};
GetAttachment: PUBLIC ENTRY PROC[h: Handle] RETURNS[REF ANY] =
{ENABLE UNWIND => NULL;
IF NOT Valid[h] THEN ERROR InvalidProcess[h];
RETURN[h.attachment]};
Valid: PUBLIC PROC[h: Handle] RETURNS[BOOLEAN] =
{RETURN[DoValid[h]]};
DoValid: PROC[h: Handle] RETURNS[BOOLEAN] =
INLINE
{RETURN[h # NIL AND h.valid AND h.psbi # PSB.PsbNull AND IsAlive[h.psbi]]};
IsAlive: PUBLIC PROC[psbi: PSB.PsbIndex] RETURNS[BOOLEAN] =
{RETURN[ProcState[ProcessOperations.IndexToHandle[psbi]].state = alive]};
ProcState: PROC[psbh: PSB.PsbHandle] RETURNS [CPSwapDefs.ProcessState] =
INLINE
{RETURN[LOOPHOLE[PSB.PDA[psbh].flags.available, CPSwapDefs.ProcessState]]};
NewCedarProcessRegistered: PUBLIC ENTRY PROC[psbi: PSB.PsbIndex] =
{ENABLE UNWIND => NULL;
handle: Handle = MapPSBIToHandle[psbi];
IF DoValid[handle] THEN ERROR;
handle.valid ← TRUE};
InvalidateCedarProcess: PUBLIC PROC[psbi: PSB.PsbIndex] =
{h: Handle;
RTProcessPrivate.InvalidateFaultingCedarProcess[psbi];
h ← MapPSBIToHandle[psbi];
h.valid ← FALSE};
-- START HERE
MapPSBIToHandle ← NEW[RTProcessPrivate.MapRecord[LAST[PSB.PsbIndex]+1]];
FOR psbi: PSB.PsbIndex IN PSB.PsbIndex
DO MapPSBIToHandle[psbi] ← processZone.NEW[Object ← [psbi: psbi]]; ENDLOOP;
-- register the RTProcess package with RTProcessPrivateImpl
RTOS.RTProcessStarted[];
END.