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 \n"; "#include \n"; "#include \n"; "#include \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 = { 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. N DeltaResourceImpl.mesa Copyright Σ 1990, 1991, 1992 by Xerox Corporation. All rights reserved. Russ Atkinson (RRA) January 9, 1991 8:40 pm PST [cmd: Handle] RETURNS [result: REF _ NIL, msg: ROPE _ NIL] CommandObject = [ in, out, err: STREAM, commandLine, command: ROPE, propertyList: List.AList, procData: CommandProcHandle] Κ +–(cedarcode) style•NewlineDelimiter ™codešΟn™Kšœ Οeœ=™HK™/—˜KšΟk œ4Ÿœ˜F˜K˜——šœŸœŸ˜ KšŸœ%Ÿœ˜4KšŸœ˜KšœŸ˜K˜KšŸœŸœŸœ˜KšŸœŸœŸœŸœ˜K˜Kšœ Ÿœ˜&K–2.2 in tabStopsšœŸœ˜$K–2.2 in tabStopsšœŸœ˜"K˜—K˜š  œŸœŸœŸœ Ÿœ˜3Kšœ ˜ Kšœ˜KšŸœ˜ K˜K˜—š  œŸœŸœ ŸœŸœ ˜8K˜K˜K˜K˜ K˜K˜&K˜K˜$K˜˜K˜—K˜-K˜K˜;K˜K˜2K˜GK˜MK˜GšŸœŸœ˜'K˜@K˜6K˜—K˜GK˜MK˜GšŸœŸœ˜'K˜@K˜6K˜—K˜K˜;K˜8K˜8K˜8K˜;K˜;K˜8K˜>K˜AK˜;K˜;K˜AK˜8K˜;K˜KšŸœ ˜K˜K˜—š  œŸœŸœŸœŸœ˜)Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜K˜K˜K˜—š œŸœŸœŸœŸœ Ÿ œŸœŸœ˜KKšœ*˜*Kšœ&˜&Kšœ ˜ Kšœ˜K˜K˜—š œŸœŸœŸœŸœŸœŸœ˜:Kšœ˜K˜K˜—š œŸœŸœŸœŸœŸœŸœ˜9Kšœ˜K˜K˜—šœŸœŸœŸœŸœŸœŸœ˜šŸœŸœ˜#Kšœ ŸœŸœ˜3KšŸœ=˜?K˜—šŸœ!Ÿœ˜)Kšœ Ÿœ!˜2KšŸœA˜CK˜—K–2.2 in tabStopsšŸœ˜K˜K˜—šŸœ Ÿœ˜–2.2 in tabStopsšŸœZŸœ˜bK–2.2 in tabStopsšŸœ˜–2.2 in tabStopsšŸœŸ˜K–2.2 in tabStopsšŸœ=˜?—–2.2 in tabStopsšŸœŸ˜K–2.2 in tabStopsšŸœ;˜=—K–2.2 in tabStopsšŸœ9˜;–2.2 in tabStopsšŸœŸ˜K–2.2 in tabStopsšŸœ;˜=—K–2.2 in tabStopsšŸœ˜K–2.2 in tabStops˜—–2.2 in tabStopsšŸœFŸœ˜NK–2.2 in tabStopsšŸœ=˜?K–2.2 in tabStopsšŸœ=˜?–2.2 in tabStopsšŸœŸ˜K–2.2 in tabStopsšŸœ;˜=—K–2.2 in tabStopsšŸœ˜K–2.2 in tabStops˜—–2.2 in tabStopsšŸœ4Ÿœ˜