-- 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.