<> <> <> DIRECTORY BasicTime USING [Pulses, GetClockPulses, PulsesToMicroseconds], EtherTesterOps USING [tsOut, Stats, counter], IO, -- using lots; Rope USING [ROPE]; EtherTesterStatsImpl: MONITOR IMPORTS BasicTime, EtherTesterOps, IO EXPORTS EtherTesterOps = BEGIN <> stats: PUBLIC EtherTesterOps.Stats; realBackground: PUBLIC LONG CARDINAL; <> oldPulses: BasicTime.Pulses; elapsedTime, recentTime: LONG CARDINAL; -- in mili seconds leftoverMicroseconds: LONG CARDINAL; StatsInit: PUBLIC PROC = BEGIN stats _ [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; oldPulses _ BasicTime.GetClockPulses[]; elapsedTime _ recentTime _ leftoverMicroseconds _ 0; realBackground _ EtherTesterOps.counter[7] _ 1; END; StatsPeek: PUBLIC PROC = BEGIN StatsUpdateClock[]; IF recentTime > 3600000 THEN BEGIN StatsPrint[TRUE]; recentTime _ recentTime - 3600000; END; END; StatsUpdateClock: ENTRY PROC = { StatsClock[] }; StatsClock: INTERNAL PROC = BEGIN now: BasicTime.Pulses _ BasicTime.GetClockPulses[]; microSec, milliSec: LONG CARDINAL; EtherTesterOps.counter[7] _ realBackground _ realBackground + 1; microSec _ leftoverMicroseconds + BasicTime.PulsesToMicroseconds[now - oldPulses]; IF microSec < 1000000 THEN RETURN; oldPulses _ now; milliSec _ microSec/1000; elapsedTime _ elapsedTime + milliSec; recentTime _ recentTime + milliSec; leftoverMicroseconds _ microSec - (milliSec*1000); END; StatsPrint: PUBLIC ENTRY PROC[partial: BOOL] = BEGIN OPEN IO; log: STREAM_ EtherTesterOps.tsOut; StatsClock[]; log.PutF[NIL, time[]]; log.PutRope[ IF partial THEN " The time so far is " ELSE " This run lasted "]; log.PutF[NIL, card[elapsedTime/1000]]; log.PutRope[" seconds.\nIt took "]; log.PutF[NIL, card[elapsedTime/realBackground]]; log.PutRope[" ms/background cycle.\n"]; IF PrintLine[stats.pktsOut, "Packets Sent OK"] THEN stats.pktsOut _ 0; IF PrintLine[stats.wdsOut, "Words Sent"] THEN stats.wdsOut _ 0; IF PrintLine[stats.collisions, "Collisions"] THEN stats.collisions _ 0; IF PrintLine[stats.coll1, "Packets with 1 collision"] THEN stats.coll1 _ 0; IF PrintLine[stats.coll2, "Packets with 2 collisions"] THEN stats.coll2 _ 0; IF PrintLine[stats.coll3, "Packets with 3 collisions"] THEN stats.coll3 _ 0; IF PrintLine[stats.coll4, "Packets with 4 collisions"] THEN stats.coll4 _ 0; IF PrintLine[stats.coll5, "Packets with 5 collisions"] THEN stats.coll5 _ 0; IF PrintLine[stats.coll6, "Packets with 6 collisions"] THEN stats.coll6 _ 0; IF PrintLine[stats.coll7, "Packets with 7 collisions"] THEN stats.coll7 _ 0; IF PrintLine[stats.coll8, "Packets with 8 collisions"] THEN stats.coll8 _ 0; IF PrintLine[stats.coll9, "Packets with 9 collisions"] THEN stats.coll9 _ 0; IF PrintLine[stats.coll10, "Packets with 10 collisions"] THEN stats.coll10 _ 0; IF PrintLine[stats.coll11, "Packets with 11 collisions"] THEN stats.coll11 _ 0; IF PrintLine[stats.coll12, "Packets with 12 collisions"] THEN stats.coll12 _ 0; IF PrintLine[stats.coll13, "Packets with 13 collisions"] THEN stats.coll13 _ 0; IF PrintLine[stats.coll14, "Packets with 14 collisions"] THEN stats.coll14 _ 0; IF PrintLine[stats.coll15, "Packets with 15 collisions"] THEN stats.coll15 _ 0; IF PrintLine[stats.collx, "Packets with funny collision mask ******"] THEN stats.collx _ 0; IF PrintLine[stats.loadOverflow, "Packets with too many collisions"] THEN stats.loadOverflow _ 0; IF PrintLine[stats.lateCollisions, "Late collisions ******"] THEN stats.lateCollisions _ 0; IF PrintLine[stats.errsOut, "Errors from Transmitter"] THEN stats.errsOut _ 0; IF PrintLine[stats.funnyOut, "Funny Output Errors ******"] THEN stats.funnyOut _ 0; IF PrintLine[stats.overrunOut, "Output overruns"] THEN stats.overrunOut _ 0; [] _ PrintLine[Mpp[stats.pktsOut], "Microsec/Pkt Sent"]; [] _ PrintLine[BitsPerSecond[stats.wdsOut], "Bits/Sec Sent"]; IF PrintLine[stats.pktsIn, "Packets Received OK"] THEN stats.pktsIn _ 0; IF PrintLine[stats.wdsIn, "Words Received"] THEN stats.wdsIn _ 0; IF PrintLine[stats.wrongLength, "Packets received with wrong length **"] THEN stats.wrongLength _ 0; IF PrintLine[stats.wrongPackets, "Packets received with at least one wrong word **"] THEN stats.wrongPackets _ 0; IF PrintLine[stats.wrongWords, "Wrong words received **"] THEN stats.wrongWords _ 0; IF PrintLine[stats.missed, "Input packets missed (no buffer)"] THEN stats.missed _ 0; IF PrintLine[stats.errsIn, "Errors from Receiver"] THEN stats.errsIn _ 0; IF PrintLine[stats.funnyIn, "Funny Input Errors ******"] THEN stats.funnyIn _ 0; IF PrintLine[stats.shortIn, "Short Packets ******"] THEN stats.shortIn _ 0; IF PrintLine[stats.longIn, "Long Packets ******"] THEN stats.longIn _ 0; IF PrintLine[stats.shortBuffer, "Buffer Overflow ******"] THEN stats.shortBuffer _ 0; IF PrintLine[stats.itIn, "Input IT only errors ******"] THEN stats.itIn _ 0; IF PrintLine[stats.crcIn, "Input CRC errors"] THEN stats.crcIn _ 0; IF PrintLine[stats.crcItIn, "Input CRC+IT errors"] THEN stats.crcItIn _ 0; IF PrintLine[stats.overrunIn, "Input overruns"] THEN stats.overrunIn _ 0; IF PrintLine[stats.bc, "Broadcast packets Received"] THEN stats.bc _ 0; IF PrintLine[stats.bcWords, "Words in Broadcast packets"] THEN stats.bcWords _ 0; IF PrintLine[stats.toMe, "Packets to ME"] THEN stats.toMe _ 0; IF PrintLine[stats.toOther, "Packets to somebody else"] THEN stats.toOther _ 0; IF PrintLine[stats.fromMe, "Packets from ME"] THEN stats.fromMe _ 0; IF PrintLine[stats.packetsEchoed, "Packets Echoed"] THEN stats.packetsEchoed _ 0; IF PrintLine[stats.packetsNotEchoed, "Packets Not Echoed (no output buffer)"] THEN stats.packetsNotEchoed _ 0; IF PrintLine[stats.lateEchos, "Late Echo Packets ****"] THEN stats.lateEchos _ 0; IF PrintLine[stats.packetsTooLongToEcho, "Packets Too Long To Echo ****"] THEN stats.packetsTooLongToEcho _ 0; IF PrintLine[stats.echosMissed, "Echos Missed"] THEN stats.echosMissed _ 0; IF PrintLine[stats.dallyForEcho, "Dallys for Echo"] THEN stats.dallyForEcho _ 0; IF PrintLine[stats.runts, "Runts"] THEN stats.runts _ 0; IF PrintLine[stats.runtsMarkedOk, "Runts marked OK *****"] THEN stats.runtsMarkedOk _ 0; IF PrintLine[stats.multicastRunts, "Runts via mullticast"] THEN stats.multicastRunts _ 0; [] _ PrintLine[Mpp[stats.pktsIn], "Microsec/Pkt Received"]; [] _ PrintLine[BitsPerSecond[stats.wdsIn], "Bits/Sec Received"]; log.PutChar['\n]; END; PrintLine: PROC[one: LONG CARDINAL, name: Rope.ROPE] RETURNS[nonZero: BOOL] = BEGIN IF one = 0 THEN RETURN[FALSE]; EtherTesterOps.tsOut.PutF[" %g %g\n", IO.card[one], IO.rope[name]]; RETURN[TRUE]; END; BitsPerSecond: PROC[wd: LONG CARDINAL] RETURNS [LONG CARDINAL] = BEGIN t: LONG CARDINAL; IF elapsedTime < 1000 THEN RETURN[0]; SELECT wd FROM < 100000000 => { t _ 16*wd; RETURN[t/(elapsedTime/1000)] }; ENDCASE => { t _ wd/(elapsedTime/1000); RETURN[16*t] }; END; Mpp: PROC[packets: LONG CARDINAL] RETURNS [LONG CARDINAL] = BEGIN t, p: LONG CARDINAL; IF packets = 0 THEN RETURN[0]; SELECT elapsedTime FROM < 2000000 => { t _ elapsedTime*1000; p _ packets }; ENDCASE => { t _ elapsedTime; p _ packets/1000; IF p = 0 THEN RETURN[0] }; RETURN[t/p]; END; END.