-- File: QueuePup.mesa - last edit: -- MAS May 19, 1980 6:23 PM -- HGM October 15, 1979 7:53 PM -- Copyright Xerox Corporation 1979, 1980 DIRECTORY StatsDefs: FROM "StatsDefs" USING [StatIncr], CommUtilDefs: FROM "CommUtilDefs" USING [GetReturnFrame], DriverDefs: FROM "DriverDefs" USING [ doDebug, doSee, doStats, Glitch, freeQueueLock, freeQueue, firstBuffer, freeQueueNotEmpty], PupDefs: FROM "PupDefs" USING [DequeuePup, EnqueuePup], BufferDefs: FROM "BufferDefs" USING [ Buffer, PupBuffer, RppBuffer, Queue, buffersToReserve], DriverTypes: FROM "DriverTypes" USING [bufferSeal, queueSeal]; QueuePup: MONITOR LOCKS DriverDefs.freeQueueLock IMPORTS StatsDefs, CommUtilDefs, DriverDefs, PupDefs EXPORTS PupDefs, BufferDefs SHARES BufferDefs = BEGIN OPEN DriverDefs, BufferDefs; QueueScrambled: PUBLIC ERROR = CODE; QueueSealBroken: PUBLIC ERROR = CODE; BufferSealBroken: PUBLIC ERROR = CODE; FreeQueueNotInitialized: PUBLIC ERROR = CODE; ExtractPupFromQueue: PUBLIC PROCEDURE [Queue, PupBuffer] RETURNS [PupBuffer] = LOOPHOLE[ExtractFromQueue]; ExtractRppFromQueue: PUBLIC PROCEDURE [Queue, RppBuffer] RETURNS [RppBuffer] = LOOPHOLE[ExtractFromQueue]; ExtractFromQueue: PUBLIC PROCEDURE [q: Queue, b: Buffer] RETURNS [Buffer] = BEGIN previousB, currentB: Buffer; IF q=NIL THEN Glitch[QueueScrambled]; IF doDebug AND q.seal#DriverTypes.queueSeal THEN Glitch[QueueSealBroken]; IF doDebug AND b.seal#DriverTypes.bufferSeal THEN Glitch[BufferSealBroken]; previousB _ NIL; currentB _ q.first; UNTIL currentB=b DO IF currentB=NIL THEN EXIT; previousB _ currentB; currentB _ currentB.next; ENDLOOP; IF currentB#NIL THEN BEGIN -- remove this buffer from the queue IF doDebug AND currentB.seal#DriverTypes.bufferSeal THEN Glitch[BufferSealBroken]; IF currentB=q.first THEN q.first _ currentB.next; IF currentB=q.last THEN q.last _ previousB; IF previousB#NIL THEN previousB.next _ currentB.next; q.length _ q.length-1; currentB.queue _ NIL; currentB.next _ NIL; IF doStats THEN StatsDefs.StatIncr[statXqueue]; END ELSE IF doStats THEN StatsDefs.StatIncr[statXqueueNIL]; RETURN[currentB]; END; GetClumpOfPupBuffers: PUBLIC ENTRY PROCEDURE [ q: Queue, n: CARDINAL, wait: BOOLEAN] = BEGIN ENABLE UNWIND => NULL; b: PupBuffer; IF doDebug AND firstBuffer=NIL THEN Glitch[FreeQueueNotInitialized]; IF doDebug AND q.seal#DriverTypes.queueSeal THEN Glitch[QueueSealBroken]; UNTIL freeQueue.length>n+buffersToReserve DO IF ~wait THEN RETURN; WAIT freeQueueNotEmpty; ENDLOOP; THROUGH [0..n) DO b _ PupDefs.DequeuePup[@freeQueue]; IF doDebug OR doSee THEN b.type _ pup; b.pupType _ data; IF doDebug THEN b.debug _ CommUtilDefs.GetReturnFrame[].accesslink; PupDefs.EnqueuePup[q,b]; ENDLOOP; END; -- initialization END. -- QueuePup(2048)