-- File: PoolCool.mesa, Last Edit: HGM October 15, 1979 8:07 PM

-- Copyright Xerox Corporation 1979, 1980

DIRECTORY
CommUtilDefs: FROM "CommUtilDefs" USING [
AllocateHyperspace, FreeHyperspace, InitializeMonitor],
DriverDefs: FROM "DriverDefs" USING [doDebug, Glitch],
BufferDefs: FROM "BufferDefs" USING [
Buffer, BufferObject, BufferPool, Dequeue, Enqueue,
QueueInitialize, QueueCleanup, ReturnFreeBuffer],
DriverTypes: FROM "DriverTypes" USING [unsealed, bufferSeal, bufferPoolSeal];

PoolCool: PROGRAM
IMPORTS CommUtilDefs, DriverDefs, BufferDefs
EXPORTS BufferDefs
SHARES BufferDefs =
BEGIN OPEN DriverDefs, BufferDefs;

-- 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];

B
ufferPoolSealBroken: PUBLIC ERROR = CODE;


BufferPoolMake: PUBLIC PROCEDURE [
pool: BufferPool, numberOfBuffers, dataWordsPerBuffer: CARDINAL] =
BEGIN
b: Buffer;
i: CARDINAL;
pool↑ ← [
LOCK: ,
freeQueue: ,
seal: DriverTypes.bufferPoolSeal,
freeQueueNotEmpty: ,
total: numberOfBuffers, reserve: 0, send: 0, recveive: 0,
dataWordsPerBuffer: dataWordsPerBuffer,
firstBuffer: NIL,
bufferSize: big,
wordsPerBuffer: dataWordsPerBuffer+overhead ];
pool.firstBuffer ←
CommUtilDefs.AllocateHyperspace[pool.wordsPerBuffer*numberOfBuffers];
CommUtilDefs.InitializeMonitor[@pool.LOCK];
QueueInitialize[@pool.freeQueue];
b ← pool.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 ← pool;
b.next ← NIL;
IF doDebug THEN b.seal ← DriverTypes.bufferSeal;
b.requeueProcedure ← ReturnFreeBuffer;
Enqueue[@pool.freeQueue,b];
b ←
b+pool.wordsPerBuffer;
ENDLOOP;
END;

BufferPoolDestroy: PUBLIC PROCEDURE [pool: BufferPool] =
BEGIN
UNTIL Dequeue[@pool.freeQueue]=NIL DO ENDLOOP;
QueueCleanup[@pool.freeQueue];
CommUtilDefs.FreeHyperspace[pool.firstBuffer];
IF doDebug THE
N pool.seal ← DriverTypes.unsealed;
END;

EnumerateBuffersInPool: PUBLIC PROCEDURE [pool: BufferPool, proc: PROCEDURE[Buffer]] =
BEGIN OPEN pool;
wordsPerBuffer: CARDINAL;
b: BufferDefs.Buffer ← firstBuffer;
i: CARDINAL;
IF doDebug AND seal=DriverTypes.bufferPoolSeal THEN Glitch[BufferPoolSealBroken];
wordsPerBuffer ← dataWordsPerBuffer+overhead;
FOR i IN [0..total) DO
proc[b];
b ← b+wordsPerBuffer;
ENDLOOP;
END;

END. -- PoolCool