-- File: QueueCold.mesa, Last Edit: HGM November 12, 1979 6:01 PM -- Copyright Xerox Corporation 1979, 1980 DIRECTORY InlineDefs: FROM "InlineDefs" USING [BITAND, LowHalf], CommUtilDefs: FROM "CommUtilDefs" USING [ AllocateHyperspace, FreeHyperspace, LockData, UnlockData, AllocateIocbs, FreeIocbs, GlobalFrame, SetTimeout, MsecToTicks], DriverDefs: FROM "DriverDefs" USING [ freeQueue, firstBuffer, bufferSize, useCount, giantVector, doDebug, Glitch, QueueCool, QueueIn, QueueOut], PupStream: FROM "PupStream", -- EXPORTS PupDefs: FROM "PupDefs", -- EXPORTS BufferDefs: FROM "BufferDefs" USING [ defaultBufferPoolSize, defaultDataWordsPerBuffer, Buffer, BufferObject, Dequeue, Enqueue, ReturnFreeBuffer, QueueInitialize, QueueCleanup], DriverTypes: FROM "DriverTypes" USING [bufferSeal]; QueueCold: MONITOR LOCKS freeQueueLock IMPORTS InlineDefs, CommUtilDefs, DriverDefs, BufferDefs EXPORTS DriverDefs, PupStream, PupDefs, BufferDefs SHARES BufferDefs = BEGIN OPEN DriverDefs, BufferDefs; freeQueueLock: PUBLIC MONITORLOCK; freeQueueNotEmpty: PUBLIC CONDITION; numberOfBuffers: PUBLIC CARDINAL _ BufferDefs.defaultBufferPoolSize; dataWordsPerBuffer: PUBLIC CARDINAL _ BufferDefs.defaultDataWordsPerBuffer; wordsPerIocb: PUBLIC CARDINAL _ 0; -- Buffers and IOCB locations must be rounded up for alignment constraints. Alto SLA Microcode needs IOCB/LCB to be EVEN. We round things up to a Quad word just in case. -- size of a buffer without any data rawOverhead: CARDINAL = SIZE[raw BufferDefs.BufferObject]; -- 1 extra for checksum pupOverhead: CARDINAL = SIZE[pupWords pup BufferDefs.BufferObject]+1; overhead: CARDINAL = MAX[ pupOverhead, SIZE[rppWords rpp BufferDefs.BufferObject]+1]; CantResetWhileActive: PUBLIC ERROR = CODE; AdjustBufferParms: PUBLIC ENTRY PROCEDURE [bufferPoolSize, bufferSize: CARDINAL] = BEGIN IF useCount#0 THEN Glitch[CantResetWhileActive]; IF bufferPoolSize#0 THEN numberOfBuffers _ bufferPoolSize; IF bufferSize#0 THEN dataWordsPerBuffer _ bufferSize; END; GetBufferParms: PUBLIC PROCEDURE RETURNS [bufferPoolSize, bufferSize: CARDINAL] = BEGIN RETURN[numberOfBuffers,dataWordsPerBuffer]; END; -- NB: wordsPerBuffer and wordsPerIocb MUST be QuadWord multiples FreeQueueMake: PUBLIC PROCEDURE = BEGIN b: Buffer; x: POINTER TO BufferObject = LOOPHOLE[6]; -- anything to avoid NIL trap i: CARDINAL; wordsPerBuffer: CARDINAL; wordsPerBuffer _ dataWordsPerBuffer+overhead; UNTIL InlineDefs.BITAND[wordsPerBuffer,3]=0 DO wordsPerBuffer _ wordsPerBuffer+1; ENDLOOP; bufferSize _ wordsPerBuffer-(@x.encapsulation-LOOPHOLE[x,POINTER]); firstBuffer _ CommUtilDefs.AllocateHyperspace[wordsPerBuffer*numberOfBuffers+3]; UNTIL InlineDefs.BITAND[InlineDefs.LowHalf[@firstBuffer.encapsulation],3]=0 DO firstBuffer _ firstBuffer+1; ENDLOOP; IF doDebug THEN BEGIN giantVector.firstBuffer _ firstBuffer; giantVector.wordsPerBuffer _ wordsPerBuffer; giantVector.bufferPoolSize _ numberOfBuffers; END; CommUtilDefs.LockData[firstBuffer]; QueueInitialize[@freeQueue]; b _ firstBuffer; FOR i IN [0..numberOfBuffers) DO b.iocbChain _ b.userData _ NIL; b.allNets _ b.bypassZeroNet _ FALSE; b.type _ raw; b.size _ big; b.pupLength _ b.length _ 0; b.bufferNumber _ i; b.pupType _ pt177; b.queue _ NIL; b.pool _ NIL; b.next _ NIL; IF doDebug THEN b.seal _ DriverTypes.bufferSeal; b.requeueProcedure _ ReturnFreeBuffer; Enqueue[@freeQueue,b]; b _ b+wordsPerBuffer; ENDLOOP; IF wordsPerIocb#0 THEN BEGIN iocb: LONG POINTER; iocb _ CommUtilDefs.AllocateIocbs[wordsPerIocb*numberOfBuffers+3]; b _ firstBuffer; FOR i IN [0..numberOfBuffers) DO -- this does NOT align each individual iocb b.iocbChain _ iocb; iocb _ iocb+wordsPerIocb; b _ b+wordsPerBuffer; ENDLOOP; END; END; FreeQueueDestroy: PUBLIC PROCEDURE = BEGIN UNTIL Dequeue[@freeQueue]=NIL DO ENDLOOP; QueueCleanup[@freeQueue]; CommUtilDefs.UnlockData[firstBuffer]; IF firstBuffer.iocbChain#NIL THEN CommUtilDefs.FreeIocbs[firstBuffer.iocbChain]; CommUtilDefs.FreeHyperspace[firstBuffer]; IF doDebug THEN BEGIN firstBuffer _ NIL; giantVector.firstBuffer _ NIL; END; END; -- initialization CommUtilDefs.SetTimeout[@freeQueueNotEmpty,CommUtilDefs.MsecToTicks[10000]]; START DriverDefs.QueueCool; START DriverDefs.QueueIn; -- Argh, QueueLocked, or QueueLockedTiny START LOOPHOLE[CommUtilDefs.GlobalFrame[Enqueue],PROGRAM]; START DriverDefs.QueueOut; IF doDebug THEN BEGIN giantVector.firstBuffer _ NIL; giantVector.freeQueue _ @freeQueue; END; END. -- QueueCold(2048)\804b9B453i123I1i49I331b17B250b14B19t10 7t0 104bi66I13B1658b16B