BEGIN
OPEN JunoKeyboard;
- - - - INTERNAL VARS
queueMax:
INTEGER = 1000;
queue:
ARRAY [0..queueMax)
OF
REF
ANY;
queueLeft, queueRight:
INT ← 0;
The active range of the queue is [queueLeft..queueRight), wrapped.
Entries are added to the right of the queue, and removed from the left.
nonEmpty: CONDITION;
ignoredCount: NAT ← 0; -- debugging: counts number of chars lost due to full queue cond.
- - - - PROCEDURES
AppendList:
PUBLIC
ENTRY
PROC [input :
LIST
OF
REF
ANY] =
BEGIN
WHILE input # NIL DO
AppendOne[input.first];
input ← input.rest
ENDLOOP;
END;
Append:
PUBLIC
ENTRY
PROC [item1, item2, item3, item4:
REF
ANY ← NIL] =
BEGIN
IF item1 # NIL THEN AppendOne[item1];
IF item2 # NIL THEN AppendOne[item2];
IF item3 # NIL THEN AppendOne[item3];
IF item4 # NIL THEN AppendOne[item4]
END;
AppendOne:
INTERNAL
PROC [item:
REF
ANY] =
BEGIN
IF (queueRight + 1) MOD queueMax = queueLeft THEN
{ignoredCount ← ignoredCount + 1; -- Can't wait for non-full; could lock world
RETURN};
queue[queueRight] ← item;
queueRight ← (queueRight + 1) MOD queueMax;
BROADCAST nonEmpty
END;
Pop:
PUBLIC
ENTRY
PROC
RETURNS [item:
REF
ANY] =
BEGIN
WHILE (queueLeft = queueRight) DO WAIT nonEmpty ENDLOOP;
item ← queue[queueLeft];
queueLeft ← (queueLeft + 1) MOD queueMax
END;
Push:
PUBLIC
ENTRY
PROC [item1, item2, item3, item4:
REF
ANY ←
NIL] =
BEGIN
IF item1 # NIL THEN PushOne[item1];
IF item2 # NIL THEN PushOne[item2];
IF item3 # NIL THEN PushOne[item3];
IF item4 # NIL THEN PushOne[item4]
END;
PushOne:
INTERNAL
PROC [item:
REF
ANY ← NIL] =
BEGIN
IF (queueRight + 1) MOD queueMax = queueLeft THEN
{ignoredCount ← ignoredCount + 1; -- Can't wait for non-full; could lock world
queueRight ← (queueRight + queueMax - 1) MOD queueMax};
queue[queueLeft] ← item;
queueLeft ← (queueLeft + queueMax - 1) MOD queueMax;
BROADCAST nonEmpty;
END;