<> <> <> <> <<>> DIRECTORY Atom, BasicTime, GGError, GGStatistics, IO, Rope; GGStatisticsImpl: CEDAR PROGRAM IMPORTS Atom, BasicTime, GGError EXPORTS GGStatistics = BEGIN Table: TYPE = REF TableObj; TableObj: TYPE = GGStatistics.TableObj; Interval: TYPE = REF IntervalObj; IntervalObj: TYPE = GGStatistics.IntervalObj; globalTable: Table; Init: PROC [] = { globalTable _ CreateTable[]; }; GlobalTable: PUBLIC PROC [] RETURNS [table: Table] = { table _ globalTable; }; ResetTable: PUBLIC PROC [table: Table] = { FOR list: LIST OF Interval _ table.intervals, list.rest UNTIL list = NIL DO ResetIntervalInternal[list.first]; ENDLOOP; }; ResetIntervalInternal: PROC [interval: Interval] = { FOR list: LIST OF Interval _ interval.subintervals, list.rest UNTIL list = NIL DO ResetIntervalInternal[list.first]; ENDLOOP; interval.starts _ 0; interval.stops _ 0; interval.unmatchedStarts _ 0; interval.startTime _ 0; interval.totalTime _ 0; interval.maxTime _ 0; interval.minTime _ LAST[LONG CARDINAL] }; CreateTable: PUBLIC PROC [] RETURNS [table: Table] = { table _ NEW[TableObj]; table.intervals _ NIL; }; CreateInterval: PUBLIC PROC [name: ATOM, subintervals: LIST OF Interval _ NIL] RETURNS [interval: Interval] = { interval _ NEW[IntervalObj _ [name: name, subintervals: subintervals, starts: 0, stops: 0, unmatchedStarts: 0, startTime: 0, totalTime: 0, maxTime: 0, maxIndex: 9999, minTime: LAST[LONG CARDINAL]]]; }; AddInterval: PUBLIC PROC [interval: Interval, table: Table] = { table.intervals _ CONS[interval, table.intervals]; }; StartInterval: PUBLIC PROC [name: ATOM, table: Table] = { interval: Interval _ FindInterval[name, table]; IF interval.starts >= interval.stops + 1 THEN { interval.starts _ interval.stops; interval.unmatchedStarts _ interval.unmatchedStarts + 1; }; interval.starts _ interval.starts + 1; interval.startTime _ BasicTime.GetClockPulses[]; }; StopInterval: PUBLIC PROC [name: ATOM, table: Table] = { interval: Interval; stopTime, elapsedTime: BasicTime.Pulses; stopTime _ BasicTime.GetClockPulses[]; interval _ FindInterval[name, table]; interval.stops _ interval.stops + 1; elapsedTime _ stopTime - interval.startTime; interval.totalTime _ interval.totalTime + elapsedTime; interval.minTime _ IF elapsedTime < interval.minTime THEN elapsedTime ELSE interval.minTime; IF elapsedTime > interval.maxTime THEN { interval.maxTime _ elapsedTime; interval.maxIndex _ interval.starts; }; }; FindInterval: PROC [name: ATOM, table: Table] RETURNS [Interval] = { sub: Interval; success: BOOL; FOR list: LIST OF Interval _ table.intervals, list.rest UNTIL list = NIL DO [sub, success] _ FindSubInterval[name, list.first]; IF success THEN RETURN[sub]; ENDLOOP; SIGNAL Problem[msg: "No such interval in this table."]; RETURN[NIL]; }; FindSubInterval: PROC [name: ATOM, interval: Interval] RETURNS [sub: Interval, success: BOOL] = { IF interval.name = name THEN RETURN[interval, TRUE]; FOR subList: LIST OF Interval _ interval.subintervals, subList.rest UNTIL subList = NIL DO [sub, success] _ FindSubInterval[name, subList.first]; IF success THEN RETURN; ENDLOOP; RETURN[NIL, FALSE]; }; <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <<};>> <<};>> <<>> PrintInterval: PROC [f: IO.STREAM, interval: Interval, nestingLevel: NAT _ 0] = { name: Rope.ROPE; totalTime, avgTime, minTime, maxTime: LONG CARDINAL; IF interval.starts # 0 THEN { FOR i: NAT IN [1..nestingLevel] DO GGError.AppendTypescript[NIL, " ", begin]; -- print a Tab on the typescript ENDLOOP; name _ Atom.GetPName[interval.name]; totalTime _ BasicTime.PulsesToMicroseconds[interval.totalTime]/1000; GGError.PutFTypescript[NIL, middle, "%g. starts: %g. total: %g. ", [rope[name]], [integer[interval.starts]], [integer[totalTime]]]; avgTime _ totalTime/interval.starts; minTime _ BasicTime.PulsesToMicroseconds[interval.minTime]/1000; maxTime _ BasicTime.PulsesToMicroseconds[interval.maxTime]/1000; GGError.PutFTypescript[NIL, end, "avg: %g. min: %g. max: %g, index: %g, overflows: %g", [integer[avgTime]], [integer[minTime]], [integer[maxTime]], [integer[interval.maxIndex]], [integer[interval.unmatchedStarts]]]; FOR children: LIST OF Interval _ interval.subintervals, children.rest UNTIL children = NIL DO PrintInterval[f, children.first, nestingLevel+1]; ENDLOOP; }; }; PrintTable: PUBLIC PROC [f: IO.STREAM, table: Table] = { FOR list: LIST OF Interval _ table.intervals, list.rest UNTIL list = NIL DO PrintInterval[f, list.first, 0]; ENDLOOP; }; Problem: PUBLIC SIGNAL [msg: Rope.ROPE] = CODE; Init[]; END.