RefQueueImpl.Mesa
last edited August 2, 1983 7:13 pm by Paul Rovner
DIRECTORY RefQueue;
RefQueueImpl: MONITOR -- protects q's
LOCKS queue USING queue: Queue
EXPORTS RefQueue
= BEGIN
Queue: TYPE = REF Object;
Object: PUBLIC TYPE = MONITORED RECORD [
nEntries: NAT,
nextIndex: NAT ← 0,
nonEmpty: CONDITION,
refs: SEQUENCE count: NAT OF REF ANY
];
New: PUBLIC PROC[nEntries: NAT] RETURNS[new: Queue] = {
new ← NEW[Object[nEntries] ← [nEntries: nEntries, LOCK:, nonEmpty:, refs: NULL]];
};
Enqueue: PUBLIC ENTRY PROC[queue: Queue, ref: REF ANY] RETURNS[full: BOOL ← FALSE] = {
ENABLE UNWIND => NULL;
IF QFull[queue] THEN RETURN[TRUE];
queue.refs[queue.nextIndex] ← ref;
queue.nextIndex ← queue.nextIndex + 1;
NOTIFY queue.nonEmpty;
};
Dequeue: PUBLIC ENTRY PROC[queue: Queue] RETURNS[ref: REF ANY] = {
ENABLE UNWIND => NULL;
WHILE QEmpty[queue] DO WAIT queue.nonEmpty ENDLOOP;
queue.nextIndex ← queue.nextIndex - 1;
ref ← queue.refs[queue.nextIndex];
queue.refs[queue.nextIndex] ← NIL;
};
IsFull: PUBLIC ENTRY PROC[queue: Queue] RETURNS[BOOL] = {
ENABLE UNWIND => NULL;
RETURN[QFull[queue]];
};
QFull: INTERNAL PROC[queue: Queue] RETURNS[BOOL] =
INLINE {RETURN[queue.nextIndex = queue.nEntries]};
IsEmpty: PUBLIC ENTRY PROC[queue: Queue] RETURNS[BOOL] = {
ENABLE UNWIND => NULL;
RETURN[QEmpty[queue]];
};
QEmpty: INTERNAL PROC[queue: Queue] RETURNS[BOOL] =
INLINE {RETURN[queue.nextIndex = 0]};
END.