-- Copyright (C) 1983, 1985 by Xerox Corporation. All rights reserved. -- ForwarderStats.mesa, HGM, 6-Aug-85 21:00:57 DIRECTORY Buffer USING [], Driver USING [GetDeviceChain, Network], ForwarderDefs USING [ Counters, GetPointerToPupGateStats, ForwardStatsEntry, TransitMatrixEntry, statGateInfoReplies, forwardVersion, forwarderStatsReply], Stats USING [StatCounterIndex, StatsGetCounters], Protocol1 USING [GetContext], PupWireFormat USING [MesaToBcplLongNumber], PupDefs USING [PupBuffer, ReturnPup], PupRouterDefs USING [NetworkContext], PupTypes USING [maxDataWordsPerGatewayPup]; ForwarderStats: PROGRAM IMPORTS PupWireFormat, Stats, ForwarderDefs, Protocol1, PupDefs, Driver EXPORTS Buffer, ForwarderDefs = BEGIN OPEN PupDefs; Network: PUBLIC TYPE = Driver.Network; stats: LONG POINTER TO ARRAY Stats.StatCounterIndex OF LONG CARDINAL = Stats.StatsGetCounters[]; -- This may be too soon (before initialization), and/or too late (page fault) firstNetwork: Driver.Network ← Driver.GetDeviceChain[]; ForwarderStats: PUBLIC PROCEDURE [b: PupBuffer] = BEGIN OPEN ForwarderDefs; packets: LONG POINTER TO ForwarderDefs.Counters; bytes: LONG POINTER TO ForwarderDefs.Counters; nets: CARDINAL; limit: CARDINAL; AddStat: PROCEDURE [s, d: CARDINAL, n: LONG CARDINAL] = BEGIN IF n = 0 THEN RETURN; IF t = limit THEN RETURN; -- Buffer full t ← t + 1; tme↑ ← [s, d, PupWireFormat.MesaToBcplLongNumber[n]]; tme ← tme + SIZE[TransitMatrixEntry]; END; n, t, length: CARDINAL ← 0; fse: LONG POINTER TO ForwardStatsEntry; tme: LONG POINTER TO TransitMatrixEntry; [packets, bytes, nets] ← ForwarderDefs.GetPointerToPupGateStats[]; fse ← LOOPHOLE[@b.pup.pupWords]; length ← SIZE[ForwardStatsEntry]; FOR from: Driver.Network ← firstNetwork, from.next UNTIL from = NIL DO fromContext: PupRouterDefs.NetworkContext ← Protocol1.GetContext[from, pup]; b.pup.pupWords[length + n] ← fromContext.pupNetNumber; n ← n + 1; ENDLOOP; length ← length + n; limit ← (PupTypes.maxDataWordsPerGatewayPup - SIZE[ForwardStatsEntry] - n)/ SIZE[TransitMatrixEntry]; tme ← LOOPHOLE[@b.pup.pupWords + length]; IF packets # NIL THEN BEGIN FOR from: Driver.Network ← firstNetwork, from.next UNTIL from = NIL DO fromContext: PupRouterDefs.NetworkContext ← Protocol1.GetContext[from, pup]; AddStat[fromContext.pupNetNumber, 0, packets[from.index + 0*nets]]; FOR to: Driver.Network ← firstNetwork, to.next UNTIL to = NIL DO toContext: PupRouterDefs.NetworkContext ← Protocol1.GetContext[to, pup]; AddStat[ fromContext.pupNetNumber, toContext.pupNetNumber, packets[ from.index + to.index*nets]]; ENDLOOP; ENDLOOP; END; IF bytes # NIL THEN BEGIN FOR from: Driver.Network ← firstNetwork, from.next UNTIL from = NIL DO fromContext: PupRouterDefs.NetworkContext ← Protocol1.GetContext[from, pup]; AddStat[fromContext.pupNetNumber, 0, bytes[from.index + 0*nets]]; FOR to: Driver.Network ← firstNetwork, to.next UNTIL to = NIL DO toContext: PupRouterDefs.NetworkContext ← Protocol1.GetContext[to, pup]; AddStat[ fromContext.pupNetNumber, toContext.pupNetNumber, bytes[ from.index + to.index*nets]]; ENDLOOP; ENDLOOP; END; length ← length + t*SIZE[TransitMatrixEntry]; fse↑ ← [ version: forwardVersion, routingInfoRequests: PupWireFormat.MesaToBcplLongNumber[ stats[statGateInfoReplies]], numberOfNetworks: n, numberOfTMEs: t]; ReturnPup[b, forwarderStatsReply, 2*length]; END; END.