-- Swapper>SwapperExceptionImpl.mesa (last edited by Knutsen on November 13, 1980 9:16 AM)
DIRECTORY
CachedRegion USING [Operation, Outcome],
Frame USING [Alloc, Free],
RuntimeInternal USING [MakeFsi],
SwapperException USING [],
SwapperPrograms USING [],
VM USING [PageNumber];
SwapperExceptionImpl: MONITOR
IMPORTS Frame, RuntimeInternal
EXPORTS SwapperException, SwapperPrograms =
BEGIN OPEN SwapperException;
QE: TYPE = RECORD [
pQEPrev: POINTER TO QE,
page: VM.PageNumber,
operation: CachedRegion.Operation,
outcome: CachedRegion.Outcome];
PQE: TYPE = POINTER TO QE;
fsiQE: CARDINAL = RuntimeInternal.MakeFsi[SIZE[QE]];
pQELast: PQE ← NIL; -- points to last of fifo queue of exception reports
report: CONDITION;
-- Instrumentation: (not necessary for operation)
currentExceptions, maxExceptions: CARDINAL ← 0;
Await: PUBLIC ENTRY PROCEDURE []
RETURNS [page: VM.PageNumber, operation: CachedRegion.Operation, outcome: CachedRegion.Outcome] =
BEGIN
pQE, pQENext: PQE;
WHILE pQELast=NIL DO WAIT report ENDLOOP; -- Wait for queue nonempty
-- Remove first report from queue and return it:
FOR pQE ← pQELast, pQE.pQEPrev WHILE pQE.pQEPrev~=NIL DO
pQENext ← pQE;
ENDLOOP;
[, page, operation, outcome] ← pQE↑;
IF pQE=pQELast THEN
pQELast ← NIL
ELSE
pQENext.pQEPrev ← NIL;
Frame.Free[pQE];
currentExceptions ← PRED[currentExceptions];
END;
Report: PUBLIC ENTRY PROCEDURE [page: VM.PageNumber, operation: CachedRegion.Operation, outcome: CachedRegion.Outcome] =
BEGIN
-- Add report to end of queue:
pQE: PQE = LOOPHOLE[Frame.Alloc[fsiQE], PQE];
currentExceptions ← SUCC[currentExceptions];
maxExceptions ← MAX[maxExceptions, currentExceptions];
pQE↑ ← [pQELast, page, operation, outcome];
pQELast ← pQE;
NOTIFY report
END;
END.
LOG
June 6, 1978 3:31 PMMcJonesCreated file (stub only).
July 31, 1978 10:53 AMMcJonesReplace stubs with real implementation.
April 28, 1980 10:18 AMForrestFrameOps => Frame.
November 13, 1980 9:16 AMKnutsenAdd instrumentation.