-- File: StatsCold.mesa, Last Edit: November 19, 1979 12:08 PM -- Copyright Xerox Corporation 1979, 1980 DIRECTORY IODefs: FROM "IODefs" USING [ CR, WriteChar, WriteLine, WriteOctal, WriteString, NewLine], OsStaticDefs: FROM "OsStaticDefs" USING [OsStatics], ProcessDefs: FROM "ProcessDefs" USING [Detach, SetTimeout], TimeDefs: FROM "TimeDefs" USING [AppendDayTime, DefaultTime, UnpackDT], StatsDefs: FROM "StatsDefs" USING [StatIncr, StatCounterIndex], StatsPrivateDefs: FROM "StatsPrivateDefs" USING [ statGrand, statText, StatPrintCounters, StatsHot, StatsPrint, StatsStrings]; StatsCold: MONITOR LOCKS statLock IMPORTS IODefs, ProcessDefs, TimeDefs, StatsDefs, StatsPrivateDefs EXPORTS StatsDefs, StatsPrivateDefs = BEGIN OPEN StatsDefs, StatsPrivateDefs; statLock: PUBLIC MONITORLOCK; initDateAndTime: STRING _ [18]; -- when we were initialized -- Note: This is not locked in core. Don't call it from interrupt routines. StatLog: PUBLIC PROCEDURE [which: StatCounterIndex, p: POINTER, l: CARDINAL] = BEGIN OPEN IODefs; -- p+l are for debugging or whatever, maybe someday it will send a packet someplace s: STRING _ statText[which]; k: CARDINAL; StatIncr[which]; StatPrintDateAndTime[]; IF s#NIL THEN WriteString[s]; WriteLine[" ********"L]; IF p=NIL THEN RETURN; WriteOctal[p]; WriteChar['^]; FOR k IN [0..MIN[l,100]) DO WriteChar[' ]; WriteOctal[(p+k)^]; ENDLOOP; WriteChar[CR]; END; StatsGetCounters: PUBLIC PROCEDURE RETURNS [ POINTER TO ARRAY StatCounterIndex OF LONG CARDINAL] = BEGIN RETURN[@statGrand]; END; StatUpdater: ENTRY PROCEDURE = BEGIN updater: CONDITION; ProcessDefs.SetTimeout[@updater,24000]; -- 20 min at 50 ms/tick DO -- forever WAIT updater; StatUpdateLocked[]; ENDLOOP; END; StatUpdate: PUBLIC ENTRY PROCEDURE = BEGIN StatUpdateLocked[]; END; -- Update various things. -- It can be called anytime, but must be called "often enough". The 39ms clock overflows every 41 min, so be sure to call it more often than that. StatsCold FORKs to a PROCESS that calls it every 20 minutes. -- Also, it should be called before looking at statGrand[StatTime or statSeconds], as in when printing things out. -- One idea to make things go faster is to actually count things in 16 bit mode, and call somebody before the small counters overflow to copy the info out and reset them. This is where that should get done, but its a hard problem because there are no MESA instructions that do a an atomic read and reset. ticks: POINTER TO CARDINAL = LOOPHOLE[430B]; -- core loc of 39ms clock msPerTick: CARDINAL = 39; -- 39 ms per tick oldTicks: CARDINAL _ ticks^; -- last copy of 39ms clock -- this is an INTEGER because time may go backwards when it gets reset seconds: POINTER TO INTEGER = LOOPHOLE[573B]; -- core loc of 1 sec clock oldSeconds: INTEGER _ seconds^; -- last copy of 1 sec clock spareSeconds: CARDINAL _ 0; StatUpdateLocked: INTERNAL PROCEDURE = BEGIN nowTicks: CARDINAL _ ticks^; recent: CARDINAL; delta: LONG CARDINAL; newSeconds: INTEGER _ seconds^; delta _ LONG[(nowTicks-oldTicks)]*msPerTick; -- lengthen before multiply oldTicks _ nowTicks; statGrand[statTime] _ statGrand[statTime]+delta; recent _ newSeconds-oldSeconds; delta _ newSeconds-oldSeconds; oldSeconds _ newSeconds; statGrand[statSeconds] _ statGrand[statSeconds]+delta; spareSeconds _ spareSeconds+recent; UNTIL spareSeconds<3600 DO spareSeconds _ spareSeconds-3600; statGrand[statHours] _ statGrand[statHours]+1; ENDLOOP; END; -- remember current date and time for header lines StatNew: PUBLIC ENTRY PROCEDURE = BEGIN OPEN TimeDefs; initDateAndTime.length _ 0; AppendDayTime[initDateAndTime,UnpackDT[DefaultTime]]; StatZap[]; END; -- reset counters, and print a here-we-go line StatStart: PUBLIC ENTRY PROCEDURE [header: STRING] = BEGIN OPEN OsStaticDefs, IODefs; StatZap[]; StatPrintDateAndTime[]; WriteString[header]; WriteString[" of "L]; WriteString[initDateAndTime]; WriteString[" on #"L]; WriteOctal[OsStatics^.SerialNumber]; WriteLine["."L]; END; -- print out current numbers StatPrintCurrent: PUBLIC ENTRY PROCEDURE = BEGIN OPEN IODefs; StatUpdateLocked[]; StatPrintTime[]; WriteLine["Current counters."L]; StatPrintCounters[@statGrand]; WriteChar[CR]; END; -- print out current numbers StatFinish: PUBLIC ENTRY PROCEDURE = BEGIN OPEN IODefs; StatUpdateLocked[]; StatPrintDateAndTime[]; WriteLine["Grand Totals."L]; StatPrintCounters[@statGrand]; WriteChar[CR]; StatZap[]; -- just in case END; -- reset the world to be nice and clean again StatZap: INTERNAL PROCEDURE = BEGIN i: StatCounterIndex; StatUpdateLocked[]; -- init most internal stuff spareSeconds _ 0; FOR i IN StatCounterIndex DO recent[i] _ statGrand[i] _ 0; ENDLOOP; END; (2048)\840b87B488b16B123b11B197b10B93i636I29t10 1t0 15t10 38t0 8t10 6t0 2t10 19t0 18t10 1t0 1t10 1t0 9t10 27t0 102t10 1t0 15t10 28t0 31t10 29t0 31b16B176t10 9t0 485b7B205b9B318b16B210b10B260b7B -- our copy of statGrand at last call to StatSince or StatReady recent: ARRAY StatCounterIndex OF LONG CARDINAL; -- setup things for StatSince or StatSummary StatReady: PUBLIC ENTRY PROCEDURE = BEGIN i: StatCounterIndex; StatUpdateLocked[]; FOR i IN StatCounterIndex DO recent[i] _ statGrand[i]; ENDLOOP; END; -- print out new numbers since last call to StatReady or StatSince StatSince: PUBLIC PROCEDURE = BEGIN OPEN IODefs; i: StatCounterIndex; temp: ARRAY StatCounterIndex OF LONG CARDINAL; GetCopies: ENTRY PROCEDURE = INLINE BEGIN StatUpdateLocked[]; FOR i IN StatCounterIndex DO temp[i]_statGrand[i]; ENDLOOP; END; GetCopies[]; FOR i IN StatCounterIndex DO recent[i] _ temp[i]-recent[i]; ENDLOOP; StatPrintTime[]; WriteLine["Recent Statistics."L]; StatPrintCounters[@recent]; WriteChar[CR]; FOR i IN StatCounterIndex DO recent[i] _ temp[i]; ENDLOOP; END; -- AppendDayTime has format of dd-mmm-yy hh:mm:ss StatPrintDateAndTime: PUBLIC PROCEDURE = BEGIN OPEN IODefs, TimeDefs; string: STRING _ [18]; IF ~NewLine[] THEN WriteChar[CR]; AppendDayTime[string,UnpackDT[DefaultTime]]; WriteString[string]; WriteChar[' ]; WriteChar[' ]; END; StatPrintTime: PROCEDURE = BEGIN OPEN IODefs, TimeDefs; i: CARDINAL; string: STRING _ [18]; AppendDayTime[string,UnpackDT[DefaultTime]]; FOR i IN [10..18) DO WriteChar[string[i]]; ENDLOOP; WriteChar[' ]; WriteChar[' ]; END; -- initialization START StatsPrivateDefs.StatsHot; START StatsPrivateDefs.StatsPrint; START StatsPrivateDefs.StatsStrings; StatNew[]; ProcessDefs.Detach[FORK StatUpdater[]]; END. (635)\160b9B221b9B116b9B443b20B225b13B