-- FIFOConnectorCardImpl.mesa
-- last edited   July 13, 1981  8:27 AM 

DIRECTORY
	Envelopes,
	FIFOConnectorCard,
	FIFOScheduler,
	Process,
	WF;

FIFOConnectorCardImpl: MONITOR
	IMPORTS FIFOScheduler, Process, WF
	EXPORTS FIFOConnectorCard = { OPEN Envelopes;

New: CONDITION;
value: CARDINAL;

dataflow: ARRAY [0..maxDataflow) OF PROCEDURE;
maxDataflow: CARDINAL = 10;
dIndex: CARDINAL ← 0;

Put: PUBLIC PROC [v: CARDINAL] = {
--	WF.WF1["Put S:%u ", v];
	StuffIt[v];
	DataflowComputation[];
	WakeUp[];
	FIFOScheduler.StandardDelay[];
	Process.Yield[];
--	WF.WF0["Put F "]
	};

Stuff: PUBLIC PROC [v: CARDINAL] = {
--	WF.WF1["  Stuff S:%b ", v];
	StuffIt[v];
	DataflowComputation[];
	WakeUp[];
	Process.Yield[];
--	WF.WF0["  Stuff F "]
	};

StuffIt: ENTRY PROC [v: CARDINAL] = {
	value ← v};

Place: PUBLIC PROC [v: CARDINAL] = {
	StuffIt[v];
	DataflowComputation[];
	};

WakeUp: ENTRY PROC = {
	BROADCAST New};

Get: PUBLIC PROC RETURNS [ret: CARDINAL] = {
--	WF.WF0["    Get S "];
	ret ← GrabIt[];
	FIFOScheduler.StandardDelay[];
--	WF.WF0["    Get F "]
	};

Grab: PUBLIC ENTRY PROC RETURNS [ret: CARDINAL] = {
--	WF.WF0["      Grab S"];
	ret ← value;
--	WF.WF0["      Grab F "]
	};

GrabIt: ENTRY PROC RETURNS[CARDINAL] = {
	RETURN[value]};

GetNew: PUBLIC PROC [v: CARDINAL] = {
--	WF.WF1["        GetNew S:%b ", v];
	FIFOScheduler.StandardDelay[];
	GetNewBody[v];
--	WF.WF0["        GetNew F"]
	};

GetNewBody: ENTRY PROC[v: CARDINAL] = {
	FIFOScheduler.NotifyQueue[];
	DO
		WAIT New;
		IF v=value THEN EXIT;
		ENDLOOP;
	FIFOScheduler.IncCurrent[];
	};

DataflowRequest: PUBLIC ENTRY PROC [p: PROCEDURE] = {
	dataflow[dIndex] ← p;
	dIndex ← dIndex+1};

DataflowComputation: PROC = {
	i: CARDINAL;
	FOR i IN [0..dIndex) DO
		dataflow[i][]
	ENDLOOP};

Process.DisableTimeout[@New];

}.