DIRECTORY BasicTime, IO, Rope; CodeTimer: CEDAR DEFINITIONS = BEGIN Problem: SIGNAL [msg: Rope.ROPE]; Table: TYPE = REF TableObj; TableObj: TYPE; Interval: TYPE = REF IntervalObj; IntervalObj: TYPE; CreateTable: PROC [tableName: ATOM _ NIL] RETURNS [table: Table]; GetTable: PROC [tableName: ATOM] RETURNS [table: Table]; ResetTable: PROC [table: Table]; ResetInterval: PROC [intervalName: ATOM, table: Table]; StartInterval: PROC [intervalName: ATOM, table: Table]; StartInt: PROC [intervalName: ATOM, tableName: ATOM]; StopInterval: PROC [intervalName: ATOM, table: Table]; StopInt: PROC [intervalName: ATOM, tableName: ATOM]; SetIntMilliseconds: PUBLIC PROC [intervalName: ATOM, startTime: CARD32, stopTime: CARD32, tableName: ATOM]; ForEachTable: PROC [proc: ForEachTableProc] RETURNS [aborted: BOOL _ FALSE]; ForEachTableProc: TYPE = PROC [tableName: ATOM, table: Table] RETURNS [done: BOOL _ FALSE]; ForEachIntervalInContext: PROC [table: Table, proc: ForEachIntervalInContextProc] RETURNS [aborted: BOOL _ FALSE]; ForEachIntervalInContextProc: TYPE = PROC [intervalName: ATOM, process: CARD, starts, totalMsec, minMsec, maxMsec, maxIndex, startsWithoutStops: CARD, level: NAT _ 0] RETURNS [done: BOOL _ FALSE]; PrintTable: PROC [f: IO.STREAM, table: Table]; PrintInterval: PROC [f: IO.STREAM, intervalName: ATOM, table: Table, nestingLevel: NAT _ 0]; PrintInt: PROC [f: IO.STREAM, intervalName: ATOM, tableName: ATOM, nestingLevel: NAT _ 0]; TimerOn: PROC; TimerOff: PROC; IntervalStatistics: TYPE = REF IntervalStatisticsObj; IntervalStatisticsObj: TYPE = RECORD [ process: CARD, -- an identifier for the Cedar process that executed this interval context: LIST OF ATOM, -- the nesting of levels when this was called from innermost to outermost starts: CARD, totalMsec: CARD, minMsec: CARD, maxMsec: CARD, maxIndex: CARD, startsWithoutStops: CARD ]; GetIntervalTotals: PROC [intervalName: ATOM, table: Table] RETURNS [starts, totalMsec, averageMsec, minMsec, maxMsec, maxIndex, startsWithoutStops: CARD]; GetIntervalStats: PROC [intervalName: ATOM, table: Table] RETURNS [stats: LIST OF IntervalStatistics]; END. ² CodeTimer.mesa Copyright Σ 1986, 1987 by Xerox Corporation. All rights reserved. Last edited by Bier on June 18, 1986 Contents: Routines for maintaining a table of average times for user-specified operations. Pier, October 13, 1987 1:56:49 pm PDT Bier, April 11, 1990 2:33:51 pm PDT Getting ready to test performance. Creates a table and registers it in a global database, so it can be retrieved by name. If a table of this name already exists, it is reset and returned. CreateTable is not strictly necessary; tables are created as needed by StartInterval and StopInterval. If tableName is NIL, CreateTable creates an anonymous table and does not register it in the global database. Retrieve a table by name. Set all of the interval times in the table to zero. [Note: in the implementation of April 11, 1990, this routine frees up most of the storage associated with table.] Set the time of the named interval to zero. A PrintTable following this call will no longer show this interval. [Note: in the implementation of April 11, 1990, this routine doesn't free up storage, it just zeros a record.] Testing performance. Equivalent to StartInterval[intervalName, GetTable[tableName]]. Equivalent to StopInterval[intervalName, GetTable[tableName]]. Equivalent to calling StartInt[intervalName, tableName] and then calling StopInt[intervalName, tableName] startTime minus stopTime milliseconds later. Printing results. Enumerates all of the CodeTimer tables in the current virtual address space. If the proc ever returns done=TRUE, then and only then aborted will be TRUE. Walks the tree of intervals. The first level of this tree consists of those intervals that were called when no other intervals were active. The children of each interval are the intervals that were called while that interval was active. Thus, each named code interval may appear several times in the tree, once for each interval that called it. Each appearance is called an interval-in-context process is an identifier for the Cedar process that executed this interval [see CodeTimerImpl to see if this is implemented yet]. intervalName is the same name that appeared in the StartInterval and StopInterval calls that define this code interval. starts is the number of times the interval was executed since the last ResetTable or ResetInterval totalMsec describes the total milliseconds spent in this interval-in-context minMsec is the shortest time taken to execute this interval-in-context since the last reset maxMsec is the longest time taken to execute this interval-in-context since the last reset maxIndex is the index, in the range [1..starts], of the execution that produced maxMsec startsWithoutStops is the number of times that StartInterval was called without a matching StopInterval. If this is not 0, there is probably a bug in the calls to CodeTimer (or the interval is currently active). level is the depth in the tree of this interval-in-context. Top-level intervals have level=0. Uses nesting structure to print out the timed call-tree of all intervals encountered since the last ResetTable. A given interval may appear several times, once for each unique call stack of CodeTimer intervals that was in place when that interval was encountered. Each instance is called an interval-in-context. All times are in milli-seconds. "n" is the number of times this interval was executed. "total" or "S" is the time spent in the interval-in-context totalled over all executions since the last ResetInterval or ResetTable. "avg" or is the average time spent per interval-in-context. "range" gives the times for the shortest and longest execution. "worst" is the number of times the interval had been entered when the longest execution took place. "errs" is the number of times the interval was started without being stopped. Like PrintTable, but prints only that subset of the tree that contains the interval in question. Prints statistics for any intervals nested within the named interval-in-contexts as well. All times are in milli-seconds. Like PrintInterval but the table is specified by name. Turning the CodeTimer machinery on and off globally. It can be left off most of the time so that it does not impair system performance. Debugging Routines, but might be useful for some clients. Returns the total statistics for an interval (totaled over all of the parent intervals in which it was encountered). Returns the statistics individually for each context in which the interval was encountered. Κ6•NewlineDelimiter ™Icodešœ™šœB™BKšœ$™$Kšœ[™[K™%K™#—K™šΟk ˜ Kšœ œ˜—K˜K˜Kšœ œ œ˜$K˜KšΟnœœ œ˜!K˜Kšœœœ ˜šœ œ˜K˜—Kšœ œœ ˜!Kšœ œ˜K˜K™"K™šž œœ  œœ˜AKšœο™ο—šžœœ œœ˜8Kšœ™—šž œœ˜ Kšœ¦™¦—šž œœœ˜7K™ΰ—K˜K™K™Kšž œœœ˜7šžœœœ œ˜5Kšœ?™?—Kšž œœœ˜6šžœœœ œ˜4Kšœ>™>—šžœœœœ œ œ œ˜kKšœ–™–—K˜K™K™š ž œœœ œœ˜LKšœš™š—Kš œœœ œœœœ˜[K˜š žœœ4œ œœ˜rK™—šœœœœ œEœ œœœœ˜ΔKšœ Οcuœ™Kšœw™wK™bKšœL™LKšœ[™[KšœZ™ZKšœW™WKšœΤ™ΤKšœ^™^K™—šž œœœœ˜.KšœΉ™ΉKšœeΟgœ΅™›—š ž œœœœœœ˜\Kšœά™ά—šžœœœœœ œœ˜ZKšœ6™6—K˜K™ˆK™Kšžœœ˜Kšžœœ˜K˜K™9K™Kšœœœ˜5šœœœ˜&Kšœ œŸB˜QKšœ œœœŸI˜`Kšœœ˜ Kšœ œ˜Kšœ œ˜Kšœ œ˜Kšœ œ˜Kšœ˜K˜K˜—š žœœœœRœ˜šK™tK™—š žœœœœ œœ˜fK™[—K˜Kšœ˜J˜—…—V>