-- File: PupRouterCold.Mesa, Last Edit: -- MAS Apr 18, 1980 6:13 PM -- HGM January 5, 1980 3:17 PM -- Taft April 18, 1983 3:31 PM -- Copyright Xerox Corporation 1979, 1980 DIRECTORY CommUtilDefs: FROM "CommUtilDefs" USING [ AllocateHeapNode, DisableTimeout, FreeHeapNode, SetTimeout, MsecToTicks], PupRouterDefs: FROM "PupRouterDefs" USING [ PupRouterIn, PupRouterOut, PupChecksums, PupErrors, inThings, outThings, checksum, routingCacheHead, routingCacheTail, pupRouterIsActive, BeSurePupIsOn, Timeout, Prober, InsertRoutingCacheEntry, DeleteRoutingCacheEntry, RoutingCacheEntry, firstSocket, dataWordsPerPup, maxHop, emptyCacheEntry, PupInputer, PupBroadcaster], DriverDefs: FROM "DriverDefs" USING [ doDebug, giantVector, Network, RouterObject, SetPupRouter, CommPackageGo, CommPackageOff, GetDeviceChain], PupStream: FROM "PupStream", -- EXPORTS PupDefs: FROM "PupDefs" USING [], BufferDefs: FROM "BufferDefs" USING [DataWordsPerPupBuffer, PupBuffer]; PupRouterCold: MONITOR LOCKS routerLock IMPORTS CommUtilDefs, PupRouterDefs, DriverDefs, BufferDefs EXPORTS PupStream, PupDefs, PupRouterDefs SHARES BufferDefs = PUBLIC BEGIN OPEN PupRouterDefs; routerLock: PUBLIC MONITORLOCK; routingTableUpdateTimeout: PUBLIC CONDITION; probeResponse: PUBLIC CONDITION; pleaseProbe: PUBLIC CONDITION; probeRetransmitTimeout: PUBLIC CONDITION; probesLeftToDo: PUBLIC CARDINAL; numberOfRoutingCacheEntries: PUBLIC CARDINAL ← 20; pupUseCount: CARDINAL ← 0; routerTimeoutFork: PROCESS; routerProberFork: PROCESS; doDebug: BOOLEAN = DriverDefs.doDebug; pupRouter: DriverDefs.RouterObject ← [ input: LOOPHOLE[PupInputer], broadcast: LOOPHOLE[PupBroadcaster], addNetwork: AddNetwork, removeNetwork: RemoveNetwork ]; PupPackageMake: PUBLIC ENTRY PROCEDURE = BEGIN firstNetwork: DriverDefs.Network; IF (pupUseCount←pupUseCount+1)>1 THEN RETURN; DriverDefs.CommPackageGo[]; dataWordsPerPup ← BufferDefs.DataWordsPerPupBuffer[]; firstNetwork ← DriverDefs.GetDeviceChain[]; routingCacheHead ← CommUtilDefs.AllocateHeapNode[ (numberOfRoutingCacheEntries+1 --extra for net zero--)*SIZE[RoutingCacheEntry]]; FOR i: CARDINAL IN [0..numberOfRoutingCacheEntries+1) DO routingCacheTail ← routingCacheHead + i*SIZE[RoutingCacheEntry]; routingCacheTail↑ ← [next: routingCacheTail+SIZE[RoutingCacheEntry], net: emptyCacheEntry, entry: [hop: maxHop+1, time: 0, route: [0], network: NIL]]; ENDLOOP; routingCacheTail.next ← NIL; pupRouterIsActive ← TRUE; IF doDebug THEN DriverDefs.giantVector.pupRoutingTable ← DESCRIPTOR[routingCacheHead, (numberOfRoutingCacheEntries+1)*SIZE[RoutingCacheEntry]]; -- The first network on the chain becomes network zero. InsertRoutingCacheEntry[[0]].entry ← [hop: 0, time: 0, route: [0], network: firstNetwork]; -- Insert routing table entries for any directly-connected networks whose numbers -- we know a priori (this happens only in gateways). FOR network: DriverDefs.Network ← firstNetwork, network.next UNTIL network=NIL DO IF network.netNumber#0 THEN InsertRoutingCacheEntry[[network.netNumber]].entry ← [hop: 0, time: 0, route: [0], network: network]; ENDLOOP; DriverDefs.SetPupRouter[@pupRouter]; routerTimeoutFork ← FORK Timeout[]; routerProberFork ← FORK Prober[]; IF firstNetwork=NIL THEN RETURN; IF firstNetwork.device=local THEN RETURN; -- avoid hanging probesLeftToDo ← 10; -- Prober will try this many times NOTIFY pleaseProbe; -- Kick Prober to life WAIT probeResponse; -- Response to probe or 10-second timeout END; PupPackageDestroy: PUBLIC PROCEDURE = BEGIN IF doDebug THEN BeSurePupIsOn[]; IF PupPackageDestroyLocked[] THEN RETURN; JOIN routerTimeoutFork; JOIN routerProberFork; CommUtilDefs.FreeHeapNode[routingCacheHead]; routingCacheHead ← routingCacheTail ← NIL; IF doDebug THEN DriverDefs.giantVector.pupRoutingTable ← DESCRIPTOR[NIL,0]; DriverDefs.CommPackageOff[]; END; PupPackageDestroyLocked: ENTRY PROCEDURE RETURNS [BOOLEAN] = INLINE BEGIN IF (pupUseCount←pupUseCount-1)#0 THEN RETURN[TRUE]; DriverDefs.SetPupRouter[NIL]; pupRouterIsActive ← FALSE; NOTIFY routingTableUpdateTimeout; NOTIFY probeRetransmitTimeout; NOTIFY pleaseProbe; RETURN[FALSE]; END; GetPupPackageUseCount: PUBLIC PROCEDURE RETURNS [CARDINAL] = BEGIN RETURN[pupUseCount]; END; AddNetwork: PUBLIC PROCEDURE [network: DriverDefs.Network] = BEGIN InsertRoutingCacheEntry[[network.netNumber]].entry ← [hop: 0, time: 0, route: [0], network: network]; END; RemoveNetwork: PUBLIC PROCEDURE [network: DriverDefs.Network] = BEGIN DeleteRoutingCacheEntry[[network.netNumber]]; END; -- Various junky routines that live here because this is very cold code SetPupStormy: PUBLIC PROCEDURE [new: BOOLEAN] = BEGIN outThings.outStormy ← inThings.inStormy ← new; END; SetBadPupProc: PUBLIC PROCEDURE [proc: PROCEDURE[BufferDefs.PupBuffer]] = BEGIN inThings.badChecksumProc ← proc; END; InspectIncomingPups: PUBLIC PROCEDURE [ new: BOOLEAN, proc: PROCEDURE[CARDINAL,BufferDefs.PupBuffer]] = BEGIN inThings.showIn ← new; inThings.inShower ← proc; END; InspectOutgoingPups: PUBLIC PROCEDURE [ new: BOOLEAN, proc: PROCEDURE[CARDINAL,BufferDefs.PupBuffer]] = BEGIN outThings.showOut ← new; outThings.outShower ← proc; END; InspectStrayPups: PUBLIC PROCEDURE [ on, seeBroadcast: BOOLEAN, proc: PROCEDURE[BufferDefs.PupBuffer] RETURNS [error: BOOLEAN]] = BEGIN inThings.watcherIsWatching ← on; inThings.watcherSeesBroadcast ← seeBroadcast; inThings.watcherCallsThis ← proc; END; SetPupCheckit: PUBLIC PROCEDURE [new: BOOLEAN] = BEGIN PupRouterDefs.checksum ← IF new THEN software ELSE none; END; UseAltoChecksumMicrocode: PUBLIC PROCEDURE = BEGIN PupRouterDefs.checksum ← alto; END; -- initialization START PupRouterDefs.PupRouterIn; START PupRouterDefs.PupRouterOut; START PupRouterDefs.PupChecksums; START PupRouterDefs.PupErrors; CommUtilDefs.SetTimeout[@routingTableUpdateTimeout,CommUtilDefs.MsecToTicks[30000]]; CommUtilDefs.SetTimeout[@probeResponse,CommUtilDefs.MsecToTicks[1000]]; CommUtilDefs.SetTimeout[@probeRetransmitTimeout, CommUtilDefs.MsecToTicks[2000]]; CommUtilDefs.DisableTimeout[@pleaseProbe]; IF doDebug THEN BEGIN DriverDefs.giantVector.firstPupSocket ← @firstSocket; END; END.