DynaStatsImpl.mesa
Copyright © 1986 by Xerox Corporation. All rights reserved.
Written By: Pradeep Sindhu September 18, 1986 4:52:07 pm PDT
Pradeep Sindhu September 26, 1986 11:49:39 pm PDT
Last Edited by: Louis Monier September 24, 1986 5:53:56 pm PDT
DIRECTORY Convert, DynaStats, DynaSeer, Histograms, IO, ViewerClasses;
DynaStatsImpl:
CEDAR
PROGRAM
IMPORTS Convert, DynaSeer, Histograms, IO
EXPORTS DynaStats =
BEGIN OPEN DynaStats;
Stats: TYPE = REF StatsRec;
StatsRec:
TYPE =
RECORD [
numberOfOccupiedCycles, numberOfBubbles, numberOfNoOps: INT ← 0,
numberOfRequests, numberOfDisplayRequests, numberOfCacheRequests: INT ← 0,
numberOfRBRqst, numberOfWBRqst, numberOfWSRqst: INT ← 0,
numberOfReplys, numberOfDisplayReplys, numberOfCacheReplys: INT ← 0,
grantLatencyHisto, replyLatencyHisto: Histograms.Histogram ← NIL,
grantLatencyViewer, replyLatencyViewer: ViewerClasses.Viewer ← NIL
];
Init:
PUBLIC PROC [handle: Handle] ~ {
stats: Stats ← NEW [StatsRec];
stats.numberOfOccupiedCycles ← stats.numberOfBubbles ← stats.numberOfNoOps ← 0;
stats.numberOfRequests ← stats.numberOfDisplayRequests ← stats.numberOfCacheRequests ← 0;
stats.numberOfRBRqst ← stats.numberOfWBRqst ← stats.numberOfWSRqst ← 0;
stats.numberOfReplys ← stats.numberOfDisplayReplys ← stats.numberOfCacheReplys ← 0;
stats.grantLatencyHisto ← Histograms.Create1D[];
stats.replyLatencyHisto ← Histograms.Create1D[];
stats.grantLatencyViewer ← Histograms.Show[h: stats.grantLatencyHisto, viewerInit: [name: "Grant Latency"], updatePeriod: 4];
stats.replyLatencyViewer ← Histograms.Show[h: stats.replyLatencyHisto, viewerInit: [name: "Reply Latency"], updatePeriod: 4];
handle.stats ← stats;
};
PrintIt:
PUBLIC
PROC [handle: Handle]
RETURNS [
BOOL] = {
RETURN [handle.numCycles <= 500]
};
AddToHistory:
PUBLIC
PROC [handle: Handle, cycle: Cycle] = {
stats: Stats ← NARROW[handle.stats];
IF PrintIt[handle] THEN PrintCycle[handle, cycle];
IF DynaSeer.IsUsefulCycle[cycle] THEN stats.numberOfOccupiedCycles ← stats.numberOfOccupiedCycles+1;
IF cycle.cmd=Bubble THEN stats.numberOfBubbles ← stats.numberOfBubbles+1;
IF cycle.cmd=NoOp THEN stats.numberOfNoOps ← stats.numberOfNoOps+1;
IF DynaSeer.IsRequestCycle[cycle]
THEN {
stats.numberOfRequests ← stats.numberOfRequests+1;
IF DynaSeer.IsDisplay[handle, cycle.deviceId] THEN stats.numberOfDisplayRequests ← stats.numberOfDisplayRequests+1;
IF DynaSeer.IsCache[handle, cycle.deviceId] THEN stats.numberOfCacheRequests ← stats.numberOfCacheRequests+1;
IF cycle.cmd=RBRqst THEN stats.numberOfRBRqst ← stats.numberOfRBRqst+1;
IF cycle.cmd=WBRqst THEN stats.numberOfWBRqst ← stats.numberOfWBRqst+1;
IF cycle.cmd=WSRqst THEN stats.numberOfWSRqst ← stats.numberOfWSRqst+1;
};
IF DynaSeer.IsReplyCycle[cycle]
THEN {
stats.numberOfReplys ← stats.numberOfReplys+1;
IF DynaSeer.IsDisplay[handle, cycle.deviceId] THEN stats.numberOfDisplayReplys ← stats.numberOfDisplayReplys+1;
IF DynaSeer.IsCache[handle, cycle.deviceId] THEN stats.numberOfCacheReplys ← stats.numberOfCacheReplys+1;
};
IF ~DynaSeer.IsDataCycle[cycle] THEN handle.lastNonDataCycle ← cycle;
IF DynaSeer.IsHeaderCycle[cycle] THEN Histograms.Increment[stats.grantLatencyHisto, cycle.grantLatency];
IF DynaSeer.IsReplyCycle[cycle] THEN Histograms.Increment[stats.replyLatencyHisto, ReplyLatency[cycle, handle.history]];
handle.history ← CONS[cycle, handle.history];
};
ReplyLatency:
PROC [cycle: Cycle, history: Cycles]
RETURNS [latency:
NAT ← 0] ~ {
FOR h: Cycles ← history, h.rest
WHILE h#
NIL
DO
latency ← latency+1;
IF cycle.data=h.first.data AND cycle.deviceId=h.first.deviceId THEN RETURN [latency]
ENDLOOP;
ERROR;
};
PrintStats:
PUBLIC PROC [handle: Handle] ~ {
stats: Stats ← NARROW[handle.stats];
IO.PutF[handle.out, "\n\n\nTotal Number of Cycles: %g", IO.int[handle.cycleNumber-1]];
IO.PutF[handle.out, "\n Number Occupied: %g", IO.int[stats.numberOfOccupiedCycles]];
IO.PutF[handle.out, "\n Number of Bubbles: %g", IO.int[stats.numberOfBubbles]];
IO.PutF[handle.out, "\n Number of NoOps: %g", IO.int[stats.numberOfNoOps]];
IO.PutF[handle.out, "\nNumber of requests: %g", IO.int[stats.numberOfRequests]];
IO.PutF[handle.out, "\n Number from display: %g", IO.int[stats.numberOfDisplayRequests]];
IO.PutF[handle.out, "\n Number from caches: %g", IO.int[stats.numberOfCacheRequests]];
IO.PutF[handle.out, "\nNumber of replys: %g (+%g pending in memory queues)", IO.int[stats.numberOfReplys], IO.int[stats.numberOfRequests-stats.numberOfReplys]];
IO.PutF[handle.out, "\n Number to display: %g", IO.int[stats.numberOfDisplayReplys]];
IO.PutF[handle.out, "\n Number to caches: %g", IO.int[stats.numberOfCacheReplys]];
IO.PutF[handle.out, "\nNumber of RBRqst: %g", IO.int[stats.numberOfRBRqst]];
IO.PutF[handle.out, "\nNumber of WBRqst: %g", IO.int[stats.numberOfWBRqst]];
IO.PutF[handle.out, "\nNumber of WSRqst: %g", IO.int[stats.numberOfWSRqst]];
};
PrintCycle:
PROC [handle: Handle, cycle: Cycle] = {
PrintCmd:
PROC [cmd: Cmd] = {
SELECT cmd
FROM
NoOp => IO.PutRope[handle.out, " NoOp "];
DataCycle => IO.PutRope[handle.out, "DataCycle "];
Bubble => IO.PutRope[handle.out, " Bubble "];
RBRqst => IO.PutRope[handle.out, "RBRqst "];
RBRply => IO.PutRope[handle.out, "RBRply "];
WBRqst => IO.PutRope[handle.out, "WBRqst "];
WBRply => IO.PutRope[handle.out, "WBRply "];
WSRqst => IO.PutRope[handle.out, "WSRqst "];
WSRply => IO.PutRope[handle.out, "WSRply "]
ENDCASE => ERROR;
};
PrintDeviceId:
PROC[id: DeviceId] = {
IO.PutRope[handle.out, Convert.RopeFromInt[id]];
};
IO.PutRope[handle.out, "\nCycle "];
IO.PutRope[handle.out, Convert.RopeFromInt[handle.cycleNumber]];
IO.PutRope[handle.out, " "];
PrintCmd[cycle.cmd];
IF cycle.cmd=NoOp OR cycle.cmd=DataCycle OR cycle.cmd=Bubble THEN RETURN;
IO.PutRope[handle.out, " DeviceId="]; PrintDeviceId[cycle.deviceId];
IO.PutRope[handle.out, " Master="]; PrintDeviceId[cycle.master];
IO.PutRope[handle.out, " Data="];
IO.PutRope[handle.out, Convert.RopeFromInt[cycle.data]];
IO.PutRope[handle.out, " GrantLatency="];
IO.PutRope[handle.out, Convert.RopeFromInt[cycle.grantLatency]];
};
END.