-- File: QueueLocked.mesa, Last Edit: HGM October 15, 1979 8:01 PM -- Copyright Xerox Corporation 1979, 1980 DIRECTORY StatsDefs: FROM "StatsDefs" USING [StatIncr], CommUtilDefs: FROM "CommUtilDefs" USING [GetReturnFrame], DriverDefs: FROM "DriverDefs" USING [ freeQueueLock, freeQueue, firstBuffer, doDebug, doSee, doStats, Glitch], PupDefs: FROM "PupDefs", -- EXPORTs BufferDefs: FROM "BufferDefs" USING [ Buffer, PupBuffer, RppBuffer, Queue], DriverTypes: FROM "DriverTypes" USING [bufferSeal, queueSeal]; QueueLocked: MONITOR LOCKS DriverDefs.freeQueueLock IMPORTS StatsDefs, CommUtilDefs, DriverDefs EXPORTS DriverDefs, PupDefs, BufferDefs SHARES BufferDefs = BEGIN OPEN DriverDefs, BufferDefs; bufferSize: PUBLIC CARDINAL; QueueScrambled: PUBLIC ERROR = CODE; QueueSealBroken: PUBLIC ERROR = CODE; BufferSealBroken: PUBLIC ERROR = CODE; FreeQueueNotInitialized: PUBLIC ERROR = CODE; -- NB: Caller must protect his own Queues. EnqueuePup: PUBLIC PROCEDURE [Queue, PupBuffer] = LOOPHOLE[Enqueue]; EnqueueRpp: PUBLIC PROCEDURE [Queue, RppBuffer] = LOOPHOLE[Enqueue]; Enqueue: PUBLIC PROCEDURE [q: Queue, b: Buffer] = BEGIN IF q=NIL OR b=NIL OR b.queue#NIL THEN Glitch[QueueScrambled]; IF doDebug AND q.seal#DriverTypes.queueSeal THEN Glitch[QueueSealBroken]; IF doDebug AND b.seal#DriverTypes.bufferSeal THEN Glitch[BufferSealBroken]; IF doDebug AND q.length#0 AND (q.first=NIL OR q.last=NIL) THEN Glitch[QueueScrambled]; IF doDebug AND q.length>256 THEN Glitch[QueueScrambled]; b.next _ NIL; IF doStats THEN StatsDefs.StatIncr[statEnqueue]; IF q.first=NIL THEN q.first_b ELSE q.last^.next_b; q.last _ b; b.queue _ q; q.length _ q.length+1; END; DequeuePup: PUBLIC PROCEDURE [Queue] RETURNS [PupBuffer] = LOOPHOLE[Dequeue]; DequeueRpp: PUBLIC PROCEDURE [Queue] RETURNS [RppBuffer] = LOOPHOLE[Dequeue]; Dequeue: PUBLIC PROCEDURE [q: Queue] RETURNS [b: Buffer] = BEGIN IF q=NIL THEN Glitch[QueueScrambled]; IF doDebug AND q.seal#DriverTypes.queueSeal THEN Glitch[QueueSealBroken]; IF (b_q.first)=NIL THEN BEGIN IF doDebug AND q.length#0 THEN Glitch[QueueScrambled]; IF doStats THEN StatsDefs.StatIncr[statDequeueNIL]; RETURN; END; IF (q.first_q.first.next)=NIL THEN q.last_NIL; IF doDebug AND q.length>256 THEN Glitch[QueueScrambled]; q.length _ q.length-1; IF doStats THEN StatsDefs.StatIncr[statDequeue]; IF b.queue#q THEN Glitch[QueueScrambled]; b.queue _ NIL; b.next _ NIL; IF doDebug AND b.seal#DriverTypes.bufferSeal THEN Glitch[BufferSealBroken]; IF doDebug AND q.length#0 AND (q.first=NIL OR q.last=NIL) THEN Glitch[QueueScrambled]; END; -- This routine is only used by device drivers to get buffers to read things into. -- NB: b.length is setup for the size of the buffer, including ALL of the encapsulation. All device drivers must fudge things themsleves since they do not use all of the encapsulation field. GetInputBuffer: PUBLIC ENTRY PROCEDURE RETURNS [b: Buffer] = BEGIN IF doDebug AND firstBuffer=NIL THEN Glitch[FreeQueueNotInitialized]; b _ Dequeue[@freeQueue]; IF b#NIL THEN BEGIN b.length _ bufferSize; IF doDebug OR doSee THEN b.type _ raw; IF doDebug THEN b.debug _ CommUtilDefs.GetReturnFrame[].accesslink; END; END; END. -- QueueLocked(2048)\497b11B378bi45I10B59b10B59b7B601b10B68b10B68b7B787i86bI4Bi56bI3Bi126bI14B