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