DeltaResourceImpl.mesa
Copyright Ó 1990, 1991, 1992 by Xerox Corporation. All rights reserved.
Russ Atkinson (RRA) January 9, 1991 8:40 pm PST
DIRECTORY BasicTime, Commander, CommanderOps, DeltaResource, IO, Rope;
DeltaResourceImpl: CEDAR PROGRAM
IMPORTS BasicTime, Commander, CommanderOps, IO, Rope
EXPORTS DeltaResource
= BEGIN
ROPE: TYPE = Rope.ROPE;
STREAM: TYPE = IO.STREAM;
TimeVal: TYPE = DeltaResource.TimeVal;
RUsage: TYPE = DeltaResource.RUsage;
Stats: TYPE = DeltaResource.Stats;
GetRUsage: PUBLIC PROC RETURNS [RUsage] = TRUSTED {
ru: RUsage;
LocalRUsage[@ru];
RETURN [ru];
};
TakeDelta: PUBLIC PROC [inner: PROC] RETURNS [Stats] = {
startUsage: RUsage ¬ [];
stopUsage: RUsage ¬ [];
pulses: BasicTime.Pulses ¬ 0;
stats: Stats;
stats.bytesAllocated ¬ GetHeapBytes[];
startUsage ¬ GetRUsage[];
pulses ¬ BasicTime.GetClockPulses[];
inner[];
pulses ¬ BasicTime.GetClockPulses[] - pulses;
stopUsage ¬ GetRUsage[];
stats.bytesAllocated ¬ GetHeapBytes[]-stats.bytesAllocated;
stats.elapsed ¬ BasicTime.PulsesToSeconds[pulses];
stats.rusage.utime.secs ¬ stopUsage.utime.secs - startUsage.utime.secs;
stats.rusage.utime.micros ¬ stopUsage.utime.micros - startUsage.utime.micros;
stats.utime ¬ stats.rusage.utime.secs + 1e-6*stats.rusage.utime.micros;
IF stats.rusage.utime.micros < 0 THEN {
stats.rusage.utime.micros ¬ stats.rusage.utime.micros + 1000000;
stats.rusage.utime.secs ¬ stats.rusage.utime.secs - 1;
};
stats.rusage.stime.secs ¬ stopUsage.stime.secs - startUsage.stime.secs;
stats.rusage.stime.micros ¬ stopUsage.stime.micros - startUsage.stime.micros;
stats.stime ¬ stats.rusage.stime.secs + 1e-6*stats.rusage.stime.micros;
IF stats.rusage.stime.micros < 0 THEN {
stats.rusage.stime.micros ¬ stats.rusage.stime.micros + 1000000;
stats.rusage.stime.secs ¬ stats.rusage.stime.secs - 1;
};
stats.rusage.maxrss ¬ stopUsage.maxrss - startUsage.maxrss;
stats.rusage.ixrss ¬ stopUsage.ixrss - startUsage.ixrss;
stats.rusage.idrss ¬ stopUsage.idrss - startUsage.idrss;
stats.rusage.isrss ¬ stopUsage.isrss - startUsage.isrss;
stats.rusage.minflt ¬ stopUsage.minflt - startUsage.minflt;
stats.rusage.majflt ¬ stopUsage.majflt - startUsage.majflt;
stats.rusage.nswap ¬ stopUsage.nswap - startUsage.nswap;
stats.rusage.inblock ¬ stopUsage.inblock - startUsage.inblock;
stats.rusage.outblock ¬ stopUsage.outblock - startUsage.outblock;
stats.rusage.msgsnd ¬ stopUsage.msgsnd - startUsage.msgsnd;
stats.rusage.msgrcv ¬ stopUsage.msgrcv - startUsage.msgrcv;
stats.rusage.nsignals ¬ stopUsage.nsignals - startUsage.nsignals;
stats.rusage.nvcsw ¬ stopUsage.nvcsw - startUsage.nvcsw;
stats.rusage.nivcsw ¬ stopUsage.nivcsw - startUsage.nivcsw;
RETURN [stats];
};
DoIncludes: PROC = TRUSTED MACHINE CODE {
"*";
"#include <sys/time.h>\n";
"#include <sys/resource.h>\n";
"#include <xr/GC.h>\n";
"#include <xr/UIO.h>\n";
"."
};
LocalRUsage: UNSAFE PROC [rp: POINTER TO RUsage] ~ UNCHECKED MACHINE CODE {
"+static void LocalRUsage (p) ptr p; {\n";
" XR←GetRUsage(RUSAGE←SELF, p);\n";
" };\n";
".LocalRUsage";
};
GetHeapBytes: PROC RETURNS [CARD] = TRUSTED MACHINE CODE {
"XR←GCTotalByteCount";
};
GetHeapSize: PROC RETURNS [CARD] = TRUSTED MACHINE CODE {
"XR←GCHeapSize";
};
GetObjectCount: PROC RETURNS [CARD] = TRUSTED MACHINE CODE {
"XR←GCTotalObjectCount";
};
DeltaCommand: Commander.CommandProc = {
[cmd: Handle] RETURNS [result: REFNIL, msg: ROPENIL]
CommandObject = [
in, out, err: STREAM, commandLine, command: ROPE,
propertyList: List.AList, procData: CommandProcHandle]
out: STREAM = cmd.out;
inner: PROC = {
result ¬ CommanderOps.DoCommand[commandLine: line, parent: cmd];
};
processArgs: PROC [line: ROPE] RETURNS [ROPE] = {
i: INT ¬ 0;
len: INT = Rope.Length[line];
WHILE i < len DO
c: CHAR ¬ Rope.Fetch[line, i];
SELECT c FROM
40C, '\t => i ¬ i + 1;
'- => {
sense: BOOL ¬ TRUE;
i ¬ i + 1;
WHILE i < len DO
SELECT Rope.Fetch[line, i] FROM
'~ => sense ¬ NOT sense;
'v, 'V => verbose ¬ sense;
'g, 'G => showGC ¬ sense;
IN ['a..'z], IN ['A..'Z], IN ['0..'9] => {};
ENDCASE => EXIT;
i ¬ i + 1;
ENDLOOP;
};
ENDCASE => EXIT;
ENDLOOP;
RETURN [Rope.Substr[line, i]];
};
verbose: BOOL ¬ FALSE;
showGC: BOOL ¬ FALSE;
line: ROPE = processArgs[cmd.commandLine];
oldHeapSize: CARD = GetHeapSize[];
oldObjectCount: CARD = GetObjectCount[];
stats: Stats = TakeDelta[inner];
newHeapSize: CARD = GetHeapSize[];
newObjectCount: CARD = GetObjectCount[];
IO.PutF1[out, "Elapsed seconds: %5.3f", [real[stats.elapsed]]];
IO.PutF1[out, ", bytes allocated: %g", [cardinal[stats.bytesAllocated]] ];
IO.PutF1[out, ", utime: %5.3f", [real[stats.utime]] ];
IO.PutF1[out, ", stime: %5.3f\n", [real[stats.stime]] ];
IF showGC THEN {
IO.PutF1[out, " GC heap size: %g", [cardinal[newHeapSize]] ];
IF newHeapSize # oldHeapSize THEN {
heapDelta: INT = LOOPHOLE[newHeapSize-oldHeapSize];
IO.PutF1[out, ", heap size change: %g", [integer[heapDelta]] ];
};
IF newObjectCount # oldObjectCount THEN {
objectDelta: CARD = newObjectCount-oldObjectCount;
IO.PutF1[out, ", objects allocated: %g", [cardinal[objectDelta]] ];
};
IO.PutChar[out, '\n];
};
IF verbose THEN {
IF (stats.rusage.maxrss + stats.rusage.ixrss + stats.rusage.idrss + stats.rusage.isrss) # 0 THEN {
IO.PutRope[out, " "];
IF stats.rusage.maxrss # 0 THEN
IO.PutF1[out, "maxrss: %g, ", [integer[stats.rusage.maxrss]] ];
IF stats.rusage.ixrss # 0 THEN
IO.PutF1[out, "ixrss: %g, ", [integer[stats.rusage.ixrss]] ];
IO.PutF1[out, "idrss: %g", [integer[stats.rusage.idrss]] ];
IF stats.rusage.isrss # 0 THEN
IO.PutF1[out, ", isrss: %g", [integer[stats.rusage.isrss]] ];
IO.PutChar[out, '\n];
};
IF (stats.rusage.minflt + stats.rusage.majflt + stats.rusage.nswap) # 0 THEN {
IO.PutF1[out, " minflt: %g", [integer[stats.rusage.minflt]] ];
IO.PutF1[out, ", majflt: %g", [integer[stats.rusage.majflt]] ];
IF stats.rusage.nswap # 0 THEN
IO.PutF1[out, ", nswap: %g", [integer[stats.rusage.nswap]] ];
IO.PutChar[out, '\n];
};
IF (stats.rusage.inblock + stats.rusage.outblock) # 0 THEN {
IO.PutF1[out, " inblock: %g", [integer[stats.rusage.inblock]] ];
IO.PutF1[out, ", outblock: %g\n", [integer[stats.rusage.outblock]] ];
};
IF (stats.rusage.msgsnd + stats.rusage.msgrcv) # 0 THEN {
IO.PutF1[out, " msgsnd: %g", [integer[stats.rusage.msgsnd]] ];
IO.PutF1[out, ", msgrcv: %g\n", [integer[stats.rusage.msgrcv]] ];
};
IF (stats.rusage.nsignals + stats.rusage.nvcsw + stats.rusage.nivcsw) # 0 THEN {
IO.PutF1[out, " nsignals: %g", [integer[stats.rusage.nsignals]] ];
IO.PutF1[out, ", nvcsw: %g", [integer[stats.rusage.nvcsw]] ];
IO.PutF1[out, ", nivcsw: %g\n", [integer[stats.rusage.nivcsw]] ];
};
};
};
deltaDoc: ROPE = "shows resource usage during the execution of the command line
-g show extra GC stats
-v show verbose system stats";
DoIncludes[];
Commander.Register["Delta", DeltaCommand, deltaDoc, $Delta, FALSE];
Commander.Register["DeltaResource", DeltaCommand, deltaDoc, $Delta, FALSE];
END.