-- RTSpongeImpl.Mesa
-- ******* NOTE COMPILE THIS /-c *********
-- last edited December 6, 1982 12:51 pm by Paul Rovner
DIRECTORY
Process USING[Detach, Priority, SetPriority, GetPriority],
ProcessInternal USING[DisableInterrupts],
ProcessOperations USING[EnableAndRequeue, ReadPSB, HandleToIndex],
PSB USING[PDA, PsbIndex],
RTOS USING[UnregisterCedarProcess],
RTSponge USING[spongePriority],
Runtime USING[GlobalFrame],
SpecialSpace USING[MakeCodeResident, MakeCodeSwappable, MakeGlobalFrameResident--, MakeGlobalFrameSwappable--];
RTSpongeImpl: MONITOR LOCKS Lock -- allows the Sponge to WAIT
IMPORTS Process, ProcessInternal, ProcessOperations, RTOS, Runtime, SpecialSpace
EXPORTS RTSponge
= BEGIN
Lock: PUBLIC MONITORLOCK;
SpongeNeeded: PUBLIC CONDITION;
SpongeRunning: PUBLIC CONDITION;
SpongeFinished: PUBLIC CONDITION;
SpongeEnabled: PUBLIC CONDITION;
useCount: PUBLIC CARDINAL ← 0;
spongeRunning: PUBLIC BOOLEAN ← FALSE;
spongeDisabled: PUBLIC BOOLEAN ← FALSE;
normalPriority: Process.Priority = Process.GetPriority[];
sponge: PROCESS;
thisModule: PROGRAM = Runtime.GlobalFrame[Sponge];
-- This guy is fired up as a detached process by the start code
Sponge: PROC =
{ RTOS.UnregisterCedarProcess[GetCurrent[]];
DO
SpongeInner[];
Yield[]; -- never let a process with a lower priority than this one run
ENDLOOP};
GetCurrent: PROC RETURNS[PSB.PsbIndex] =
INLINE
{RETURN[ProcessOperations.HandleToIndex[ProcessOperations.ReadPSB[]]]};
SpongeInner: ENTRY PROC = INLINE
{WHILE useCount = 0
DO IF spongeRunning
THEN {Process.SetPriority[normalPriority];
-- SpecialSpace.MakeGlobalFrameSwappable[RTSpongeImpl];
SpecialSpace.MakeCodeSwappable[thisModule];
spongeRunning ← FALSE};
WAIT SpongeNeeded
ENDLOOP;
IF NOT spongeRunning
THEN {SpecialSpace.MakeCodeResident[thisModule];
SpecialSpace.MakeGlobalFrameResident[RTSpongeImpl];
Process.SetPriority[RTSponge.spongePriority];
spongeRunning ← TRUE;
NOTIFY SpongeRunning}};
Yield: PROC = INLINE
{ ProcessInternal.DisableInterrupts[]; -- (to cancel subsequent enable)
ProcessOperations.EnableAndRequeue[@PSB.PDA.ready,
@PSB.PDA.ready,
ProcessOperations.ReadPSB[]]};
-- START HERE
Process.Detach[sponge ← FORK Sponge];
END.