DIRECTORY BufferDefs USING [Buffer, Dequeue, Enqueue, Queue, QueueCleanup, QueueInitialize, QueueLength, QueueObject], CommFlags USING [doStats, doDebug], DriverDefs USING [GetGiantVector, Network, ReturnFreeBuffer, Router, RouterObject], Process USING [SetTimeout, MsecToTicks], SpecialCommunication USING [SpyProc], StatsDefs USING [StatIncr]; DispatcherImpl: MONITOR IMPORTS BufferDefs, DriverDefs, Process, StatsDefs EXPORTS BufferDefs, DriverDefs, SpecialCommunication SHARES BufferDefs = BEGIN Network: PUBLIC TYPE = DriverDefs.Network; mainFork: PROCESS; dispatcherPleaseDie: BOOLEAN; dispatcherReady: CONDITION; globalInputQueue: BufferDefs.Queue = NEW[BufferDefs.QueueObject]; globalOutputQueue: BufferDefs.Queue = NEW[BufferDefs.QueueObject]; pupRouter, oisRouter: PUBLIC DriverDefs.Router; dummyRouter: DriverDefs.Router; dummyRouterObject: DriverDefs.RouterObject _ [input: DummyInputer, broadcast: DummyBroadcaster, addNetwork: DummyAddDelete, removeNetwork: DummyAddDelete, stateChanged: DummyStateChanged]; bufferSpy: SpecialCommunication.SpyProc _ NIL; SetSpyProc: PUBLIC PROCEDURE [spy: SpecialCommunication.SpyProc] = BEGIN bufferSpy _ spy; END; DummyInputer: PROCEDURE [b: BufferDefs.Buffer] = BEGIN IF CommFlags.doStats THEN StatsDefs.StatIncr[statPacketsDiscarded]; b.requeueProcedure[b]; END; DummyBroadcaster: PROCEDURE [b: BufferDefs.Buffer] = BEGIN b.requeueProcedure[b]; END; DummyAddDelete: PROCEDURE [Network] = BEGIN END; DummyStateChanged: PROCEDURE [Network] = BEGIN END; SetPupRouter: PUBLIC PROCEDURE [router: DriverDefs.Router] = BEGIN IF router = NIL THEN router _ @dummyRouterObject; pupRouter _ router; END; SetOisRouter: PUBLIC PROCEDURE [router: DriverDefs.Router] = BEGIN IF router = NIL THEN router _ @dummyRouterObject; oisRouter _ router; END; GetPupRouter: PUBLIC PROCEDURE RETURNS [DriverDefs.Router] = BEGIN RETURN[pupRouter]; END; GetOisRouter: PUBLIC PROCEDURE RETURNS [DriverDefs.Router] = BEGIN RETURN[oisRouter]; END; DispatcherOn: PUBLIC PROCEDURE = BEGIN bufferSpy _ NIL; dispatcherPleaseDie _ FALSE; BufferDefs.QueueInitialize[globalInputQueue]; BufferDefs.QueueInitialize[globalOutputQueue]; mainFork _ FORK MainDispatcher[]; END; DispatcherOff: PUBLIC PROCEDURE = BEGIN DispatcherOffLocked[]; JOIN mainFork; BufferDefs.QueueCleanup[globalInputQueue]; BufferDefs.QueueCleanup[globalOutputQueue]; END; DispatcherOffLocked: ENTRY PROCEDURE = INLINE BEGIN dispatcherPleaseDie _ TRUE; NOTIFY dispatcherReady; END; MainDispatcher: PUBLIC PROCEDURE = BEGIN b: BufferDefs.Buffer; network: Network; UNTIL dispatcherPleaseDie DO WHILE BufferDefs.QueueLength[globalOutputQueue] # 0 DO b _ GrabOutputBuffer[]; IF b.allNets THEN SendToNextNetwork[b] ELSE b.requeueProcedure[b]; ENDLOOP; IF BufferDefs.QueueLength[globalInputQueue] # 0 THEN BEGIN b _ GrabInputBuffer[]; IF (bufferSpy = NIL) OR bufferSpy[b] THEN BEGIN network _ b.network; SELECT network.decapsulateBuffer[b] FROM pup => BEGIN b.type _ pup; pupRouter.input[b]; END; ois => BEGIN b.type _ ois; oisRouter.input[b]; END; rejected => dummyRouter.input[b]; processed => NULL; ENDCASE => ERROR; -- UnknownDecapsulation END; -- end of process input buffer clause LOOP; END; -- end of input queue not empty clause Wait[]; ENDLOOP; END; GrabOutputBuffer: ENTRY PROCEDURE RETURNS [BufferDefs.Buffer] = INLINE BEGIN RETURN[BufferDefs.Dequeue[globalOutputQueue]]; END; GrabInputBuffer: ENTRY PROCEDURE RETURNS [BufferDefs.Buffer] = INLINE BEGIN RETURN[BufferDefs.Dequeue[globalInputQueue]]; END; Wait: ENTRY PROCEDURE = INLINE BEGIN IF BufferDefs.QueueLength[globalInputQueue] = 0 AND BufferDefs.QueueLength[ globalOutputQueue] = 0 THEN WAIT dispatcherReady; END; SendToNextNetwork: PROCEDURE [b: BufferDefs.Buffer] = BEGIN network: Network _ b.network; b.network _ network _ network.next; IF network = NIL THEN BEGIN b.allNets _ FALSE; -- this is where it gets turned off b.requeueProcedure[b]; RETURN; END; SELECT b.type FROM pup => BEGIN pupRouter.broadcast[b]; -- this requeues b END; ois => BEGIN oisRouter.broadcast[b]; -- this requeues b END; ENDCASE => ERROR; -- dispatcher only sends out pups or ois's END; PutOnGlobalInputQueue: PUBLIC ENTRY PROCEDURE [b: BufferDefs.Buffer] = BEGIN BufferDefs.Enqueue[globalInputQueue, b]; NOTIFY dispatcherReady; END; PutOnGlobalDoneQueue: PUBLIC PROCEDURE [b: BufferDefs.Buffer] = BEGIN IF ~b.allNets AND b.requeueProcedure = DriverDefs.ReturnFreeBuffer THEN DriverDefs.ReturnFreeBuffer[b] ELSE PutOnGlobalDoneQueueLocked[b]; END; PutOnGlobalDoneQueueLocked: ENTRY PROCEDURE [b: BufferDefs.Buffer] = INLINE BEGIN BufferDefs.Enqueue[globalOutputQueue, b]; NOTIFY dispatcherReady; END; pupRouter _ @dummyRouterObject; oisRouter _ @dummyRouterObject; dummyRouter _ @dummyRouterObject; Process.SetTimeout[@dispatcherReady, Process.MsecToTicks[30000]]; IF CommFlags.doDebug THEN BEGIN DriverDefs.GetGiantVector[].globalInputQueue _ globalInputQueue; DriverDefs.GetGiantVector[].globalOutputQueue _ globalOutputQueue; END; END. -- DispatcherImpl module LOG Time: April 21, 1980 2:56 PM By: Dalal Action: created file for Pilot 5.0. Time: April 21, 1980 2:57 PM By: Dalal Action: merged the dispatchers. Time: May 7, 1980 10:34 AM By: BLyon Action: Made pupRouter & oisRouter PUBLIC (they are used by Boss). Time: May 8, 1980 1:24 PM By: BLyon Action: Made PutOnGlobalDoneQueue more efficient (hopefully it still works). DispatcherImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. BLyon on: March 21, 1981 10:47 AM EXPORTed TYPEs interface of peeking Cold procedures Hot procedures give back free buffers first give it to the right router, and it requeues the buffer dangerous we are playing with monitor data Locked procedures These are called from interrupt routines on the Alto; they must be locked in memory. This test avoids an unnecessary process switch in returning buffers to system pool. initialization Κ˜codešœ™Kšœ Οmœ1™K˜—Kšœ™K˜šŸœžœž œ˜"Kšž˜K˜K˜šžœž˜šžœ/ž˜6Kšœ™K˜Kšžœ žœžœ˜BKšžœ˜—šžœ.ž˜4Kšž˜K˜šžœžœžœž˜)Kšž˜K˜Kšœ7™7šžœž˜(˜Kšž˜K˜ K˜Kšžœ˜—˜Kšž˜K˜ K˜Kšžœ˜—K˜!Kšœ žœ˜KšžœžœΟc˜*—Kšžœ %˜*—Kšžœ˜Kšžœ &˜+—K˜Kšžœ˜—Kšžœ˜K˜—š Ÿœžœž œžœž˜FKšžœžœ)žœ˜9K˜—š Ÿœžœž œžœž˜EKšžœžœ(žœ˜8K˜—šŸœžœž œž˜Kšž˜šžœ.žœ˜KKšœžœžœ˜1—Kšžœ˜K˜—šŸœž œ˜5Kšž˜K˜K˜#Kšœ*™*šžœ žœž˜Kšž˜Kšœ žœ #˜7K˜Kšžœ˜Kšžœ˜—šžœž˜˜Kšž˜Kšœ ˜*Kšžœ˜—˜Kšž˜Kšœ ˜*Kšžœ˜—Kšžœžœ *˜<—Kšžœ˜K˜—Kšœ™KšœT™TK˜šŸœžœžœž œ˜FKšžœ*žœžœ˜KK˜—šŸœžœž œ˜?Kšž˜KšœS™Sšžœ žœ2ž˜GK˜—Kšžœ˜#Kšžœ˜K˜—šŸœžœž œž˜KKšžœ+žœžœ˜LK˜—Kšœ™K˜K˜K˜!K˜Ašžœž˜Kšž˜K˜@K˜BKšžœ˜K˜—Kšžœ ˜K˜—Kšž˜K˜Kšœžœ0˜MKšœžœ,˜IKšœžœ0žœ˜jKšœžœY˜sK˜K˜—…— ?