-- ConnectorImpl.mesa
-- last edited 23-Nov-81 16:51:43
DIRECTORY
Connector,
Scheduler,
Process;
ConnectorImpl: MONITOR
IMPORTS Scheduler, Process
EXPORTS Connector = {
Node: PUBLIC TYPE = RECORD [
value: REF ANY,
cond: CONDITION,
max: CARDINAL ← 0,
body: SEQUENCE size: [0..LAST[INTEGER]] OF RECORD [
choice: PrivateChoice,
ret: CARDINAL,
direction: {Up, Down, Change}]
];
PrivateHandle: TYPE = REF Node;
ChoiceNode: PUBLIC TYPE = RECORD [
response: CARDINAL,
cond: CONDITION];
PrivateChoice: TYPE = REF ChoiceNode;
CreateChoice: PUBLIC PROC RETURNS [PrivateChoice] = {
choice: PrivateChoice ← NEW[ChoiceNode];
Process.DisableTimeout[@choice.cond];
RETURN[choice]};
RegisterUp: PUBLIC PROC [choice: PrivateChoice, retValue: CARDINAL, port: PrivateHandle] = {
index: CARDINAL ← port.max ← port.max+1;
port.body[index] ← [choice, retValue, Up]};
GetChoice: PUBLIC ENTRY PROC [choice: PrivateChoice] RETURNS [CARDINAL] = {
Scheduler.NotifyQueue[];
WAIT choice.cond;
RETURN[choice.response]};
Create: PUBLIC PROC [size: CARDINAL] RETURNS [PrivateHandle] = {
RETURN[NEW[Node[size]]]};
Put: PUBLIC PROC [n: PrivateHandle, v: REF ANY] = {
-- WF.WF1["Put S:%u ", v];
StuffIt[n, v];
WakeUp[n];
-- Scheduler.StandardDelay[];
Process.Yield[];
-- WF.WF0["Put F "]
};
Stuff: PUBLIC PROC [n: PrivateHandle, v: REF ANY] = {
-- WF.WF1[" Stuff S:%b ", v];
StuffIt[n, v];
WakeUp[n];
Process.Yield[];
-- WF.WF0[" Stuff F "]
};
StuffIt: ENTRY PROC [n: PrivateHandle, v: REF ANY] = {
n.value ← v};
Place: PUBLIC PROC [n: PrivateHandle, v: REF ANY] = {
StuffIt[n, v];
};
Get: PUBLIC PROC [n: PrivateHandle] RETURNS [ret: REF ANY] = {
-- WF.WF0[" Get S "];
ret ← GrabIt[n];
IF ret=NIL THEN ERROR;
Process.Yield[]
-- Scheduler.StandardDelay[];
-- WF.WF0[" Get F "]
};
Grab: PUBLIC ENTRY PROC [n: PrivateHandle] RETURNS [ret: REF ANY] = {
-- WF.WF0[" Grab S"];
ret ← n.value;
-- WF.WF0[" Grab F "]
};
GrabIt: ENTRY PROC [n: PrivateHandle] RETURNS[REF ANY] = {
RETURN[n.value]};
GetNew: PUBLIC PROC [n: PrivateHandle, v: BOOLEAN] = {
-- WF.WF1[" GetNew S:%b ", v];
Scheduler.StandardDelay[];
GetNewBody[n, v];
-- WF.WF0[" GetNew F"]
};
GetNewBody: ENTRY PROC[n: PrivateHandle, v: BOOLEAN] = {
Scheduler.NotifyQueue[];
DO
WAIT n.cond;
IF v=NARROW[n.value, REF BOOLEAN]↑ THEN EXIT;
ENDLOOP;
Scheduler.IncCurrent[];
};
WakeUp: ENTRY PROC [h: PrivateHandle] = {
BROADCAST h.cond};
}.