-- 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.