PageSpaceMon.mesa
Copyright Ó 1992 by Xerox Corporation. All rights reserved.
Mna, September 27, 1991 10:04 am PDT
Weiser, May 26, 1992 10:01 pm PDT
DIRECTORY
Buttons USING [Button, Create, ReLabel, SetDisplayStyle],
Commander USING [CommandProc, Register],
Debugger,
IO,
Process USING [Detach, Pause, SecondsToTicks],
UserProfile USING [CallWhenProfileChanges, Number, ProfileChangedProc],
PFS,
Rope,
UnixSysCallExtensions,
UXStrings, UnixTypes,
ViewerClasses USING [ClickProc];
PageSpaceMon: CEDAR MONITOR
IMPORTS Buttons, Commander, --Debugger,-- IO, PFS, Process, UnixSysCallExtensions, UserProfile, UXStrings, Rope
~
BEGIN
ROPE: TYPE ~ Rope.ROPE;
STREAM: TYPE ~ IO.STREAM;
defaultCheckFreqInSeconds: INTEGER = 60;
defaultWarningLevel: INTEGER = 100; -- in kBytes
outputFile: ROPE = "/tmp/pstat.out";
commandName: ROPE = "/etc/pstat -s";
devNull: UnixTypes.CHARPtr ¬ UXStrings.Create["/dev/null"];
buttonLabel: ROPE ¬ "Page Space: ";
checkFreq: INTEGER;
warningLevel: INTEGER;
highlighted: BOOLEAN ¬ FALSE;
uxcommandname: UnixTypes.CHARPtr ¬ UXStrings.Create[commandName];
uxoutputfile: UnixTypes.CHARPtr ¬ UXStrings.Create[outputFile];
theButton: Buttons.Button ¬ NIL;
PageSpaceButton:
ENTRY Commander.CommandProc = {
IF theButton #
NIL
THEN {
IO.PutRope[cmd.out, "Page Space Monitor Button already created.\n"];
RETURN;
};
theButton ¬ Buttons.Create[
info: [name: buttonLabel], proc: DisplayPSLeft, fork: TRUE,
documentation: "create page space monitor button"];
NoteProfileChange[firstTime]; -- get initial values from profile
UserProfile.CallWhenProfileChanges[NoteProfileChange];
TRUSTED {Process.Detach[FORK PageSpaceWatcher[]]};
};
PageSpaceWatcher:
PROC ~ {
DO
ENABLE ABORTED => LOOP;
DisplayPSLeft[theButton];
Process.Pause[Process.SecondsToTicks[checkFreq]];
ENDLOOP;
};
DisplayPSLeft:
ENTRY ViewerClasses.ClickProc ~ {
swapLeftInK: INTEGER;
newName: ROPE;
XRConsoleMsgInner:
PROC [m: UXStrings.CString] ~
TRUSTED
MACHINE
CODE { "XR𡤌onsoleMsg" };
DebugMsg:
PROC [r: Rope.
ROPE] ~
TRUSTED {
text: REF TEXT;
text ¬ Rope.ToRefText[r];
XRConsoleMsgInner[UXStrings.ViewRefText[text]];
};
DebugMsg: PROC [r: Rope.ROPE] ~ TRUSTED {
Debugger.SystemPutRope[r];
};
GetSwapSpaceLeft:
PROC []
RETURNS [spaceLeft:
INTEGER] ~ {
-- returns -1 on error
res: INTEGER;
[res] ¬ UnixSysCallExtensions.Spawn[uxcommandname, devNull, uxoutputfile, devNull];
IF res = -1
THEN {
DebugMsg["PageSpaceMonButton: Spawn failed\n"];
spaceLeft ¬ -1;
}
ELSE {
-- read pstat output (highly sunos dependent)
ENABLE
IO.EndOfStream,
PFS.Error => {
DebugMsg["PageSpaceMonButton: end of output seen unexpectedly"];
spaceLeft ¬ -1;
CONTINUE;
};
s : STREAM ¬ PFS.StreamOpen[PFS.PathFromRope[outputFile]];
WHILE
IO.GetChar[s] ~= ',
DO
-- advance to comma after used
NULL;
ENDLOOP;
[] ¬ IO.GetChar[s]; -- get space char
spaceLeft ¬ IO.GetInt[s]; -- get space left
};
};
swapLeftInK ¬ GetSwapSpaceLeft[];
IF swapLeftInK = -1
THEN {
newName ¬ "Page Space: Error";
}
ELSE {
IF swapLeftInK >= 1000 THEN
[newName] ¬ IO.PutFR1["Page Space: %gMb", IO.int[swapLeftInK / 1000]]
ELSE
[newName] ¬ IO.PutFR1["Page Space: %gKb", IO.int[swapLeftInK]];
};
Buttons.ReLabel[button: theButton, newName: newName, paint: TRUE];
IF swapLeftInK < warningLevel
THEN {
IF ~highlighted
THEN {
Buttons.SetDisplayStyle[theButton, $WhiteOnBlack];
highlighted ¬ TRUE;
}
}
ELSE {
IF highlighted
THEN {
Buttons.SetDisplayStyle[theButton, $BlackOnWhite];
highlighted ¬ FALSE;
}
};
};
NoteProfileChange: UserProfile.ProfileChangedProc ~ {
checkFreq ¬ MAX[UserProfile.Number["PageSpaceMonitor.CheckFrequency", defaultCheckFreqInSeconds], 0];
warningLevel ¬ MAX[UserProfile.Number["PageSpaceMonitor.WarningLevel", defaultWarningLevel], 0];
};
Commander.Register["PageSpaceMonButton", PageSpaceButton, "create page space monitor button"];
END.