-- File: PoolHot.mesa,  Last Edit: HGM  July 18, 1979  11:32 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],
  BufferDefs: FROM "BufferDefs" USING [
    Buffer, BufferPool, Enqueue, Dequeue, ReturnFreeBuffer],
  DriverTypes: FROM "DriverTypes" USING [bufferPoolSeal];
PoolHot: MONITOR LOCKS pool USING pool: BufferDefs.BufferPool
  IMPORTS StatsDefs, CommUtilDefs, DriverDefs, BufferDefs
  EXPORTS BufferDefs
  SHARES BufferDefs =
BEGIN OPEN DriverDefs, BufferDefs;
QueueScrambled: PUBLIC ERROR = CODE;
PoolSealBroken: PUBLIC ERROR = CODE;
BufferSealBroken: PUBLIC ERROR = CODE;
BufferPoolNotInitialized: PUBLIC ERROR = CODE;
GetBufferFromPool: PUBLIC ENTRY PROCEDURE [pool: BufferPool] RETURNS [b: Buffer] =
  BEGIN OPEN pool;
  IF doDebug AND seal#DriverTypes.bufferPoolSeal THEN Glitch[PoolSealBroken];
  IF doDebug AND firstBuffer=NIL THEN Glitch[BufferPoolNotInitialized];
  IF doStats AND ~freeQueue.length>reserve THEN
    StatsDefs.StatIncr[statBufferWaits];
  UNTIL freeQueue.length>reserve DO WAIT freeQueueNotEmpty; ENDLOOP;
  b ← Dequeue[@freeQueue];
  IF doDebug AND b=NIL THEN Glitch[QueueScrambled];
  IF doDebug OR doSee THEN b.type ← raw;
  IF doDebug THEN b.debug ← CommUtilDefs.GetReturnFrame[].accesslink;
  END;
MaybeGetBufferFromPool: PUBLIC ENTRY PROCEDURE [pool: BufferPool] RETURNS [b: Buffer] =
  BEGIN OPEN pool;
  IF doStats AND pool.seal#DriverTypes.bufferPoolSeal THEN Glitch[PoolSealBroken];
  IF doDebug AND firstBuffer=NIL THEN Glitch[BufferPoolNotInitialized];
  IF doStats AND freeQueue.length=0 THEN StatsDefs.StatIncr[statBufferWaits];
  b ← Dequeue[@freeQueue];
  IF b#NIL THEN
    BEGIN
    IF doDebug OR doSee THEN b.type ← raw;
    IF doDebug THEN b.debug ← CommUtilDefs.GetReturnFrame[].accesslink;
    END;
  END;
ReturnBufferToPool: PUBLIC ENTRY PROCEDURE [pool: BufferPool, b: Buffer] =
  BEGIN
  IF doStats AND pool.seal#DriverTypes.bufferPoolSeal THEN Glitch[PoolSealBroken];
  b.requeueProcedure ← ReturnFreeBuffer;
  b.network ← NIL;
  Enqueue[@pool.freeQueue,b];
  BROADCAST pool.freeQueueNotEmpty;
  END;
BuffersLeftInPool: PUBLIC ENTRY PROCEDURE [pool: BufferPool] RETURNS [CARDINAL] =
  BEGIN
  IF doStats AND pool.seal#DriverTypes.bufferPoolSeal THEN Glitch[PoolSealBroken];
  RETURN[pool.freeQueue.length];
  END;
END.  -- PoolHot