-- File: MDSWatcher.mesa
-- Last edited by Levin: 10-Sep-80 18:46:53
-- Andrew Birrell 16-Oct-80 18:30:01
DIRECTORY
LogDefs USING [DisplayNumber],
ProcessDefs USING [Detach, Pause, SecondsToTicks],
ProcessOps USING[ FirstProcess, LastProcess ],
PSBDefs USING[ ProcessHandle, PSB ],
SegmentDefs USING [SegmentHandle],
SwapperOps USING [Page, PageMap, PageStatus, Status, systemTable];
MDSWatcher: PROGRAM
IMPORTS LogDefs, ProcessDefs, SwapperOps =
BEGIN OPEN SwapperOps;
pageMap: PageMap = systemTable.mdsMap;
Init: PROCEDURE =
BEGIN
availablePages ← 0;
availablePSBs ← 0;
LogDefs.DisplayNumber["Free MDS"L, [short[@availablePages]]];
LogDefs.DisplayNumber["Free PSBs"L, [short[@availablePSBs]]];
END;
WatchMDS: PROCEDURE =
BEGIN
DO
available: CARDINAL ← 0;
page: CARDINAL ← FIRST[Page];
UNTIL page > LAST[Page] DO
seg: SegmentDefs.SegmentHandle;
status: PageStatus;
inc: CARDINAL ← 1;
[seg, status] ← Status[page];
SELECT status FROM
inuse =>
WITH s: seg SELECT FROM
file =>
{inc ← s.pages; IF s.lock = 0 THEN available ← available + s.pages};
data => inc ← s.pages;
ENDCASE;
busy => NULL;
free => available ← available + 1;
ENDCASE;
page ← page + inc;
ENDLOOP;
availablePages ← available;
available ← 0;
FOR p: PSBDefs.ProcessHandle ← ProcessOps.FirstProcess↑,
p + SIZE[PSBDefs.PSB]
UNTIL p = ProcessOps.LastProcess↑
DO IF p.state = dead THEN available ← available+1; ENDLOOP;
availablePSBs ← available;
ProcessDefs.Pause[ProcessDefs.SecondsToTicks[60]];
ENDLOOP;
END;
availablePages: CARDINAL;
availablePSBs: CARDINAL;
Init[];
ProcessDefs.Detach[FORK WatchMDS[]];
END.