MakeDoAuxImpl.Mesa
Last Edited by: Spreitzer, September 4, 1985 10:57:35 pm PDT
DIRECTORY Basics, BasicTime, CedarProcess, Commander, CommandTool, IO, List, MakeDo, MakeDoPrivate, Menus, PrincOpsUtils, Process, ProcessProps, RedBlackTree, Rope, ViewerClasses, ViewerIO;
MakeDoAuxImpl: CEDAR MONITOR
IMPORTS BasicTime, IO, List, MakeDo, MakeDoPrivate, ProcessProps, RedBlackTree, Rope
EXPORTS MakeDo, MakeDoPrivate
=
INVARIANT
logs describes allocation of log viewers.
visitCount is unique for each invocation of NewVisit.
c.lastVisit = visit => c.computed says whether to think hard.
dependency graph is reachable from nodes.
Job is consistent.
BEGIN OPEN MakeDo, MakeDoPrivate;
NodeRep: PUBLIC TYPE = MakeDoPrivate.NodeRep;
CommandRep: PUBLIC TYPE = MakeDoPrivate.CommandRep;
visitCount: CARDINAL ← 0;
chKey: ATOM ← $CommanderHandle;
GetCommanderHandle: PUBLIC PROC RETURNS [ch: Commander.Handle] = {
ch ← NARROW[List.Assoc[chKey, ProcessProps.GetPropList[]]];
IF ch = NIL THEN ERROR;
};
fineTime: BOOLFALSE;
Log: PUBLIC PROC [depth: INTEGER, fmt: ROPE, v1, v2, v3, v4, v5: IO.Value ← [null[]]] =
BEGIN
out: IO.STREAM ← GetCommanderHandle[].out;
IF fineTime THEN out.PutF["%g:", IO.card[BasicTime.GetClockPulses[]]];
FOR i: INT IN [0 .. depth) DO out.PutChar['\t] ENDLOOP;
out.PutF[fmt, v1, v2, v3, v4, v5];
out.PutChar['\n];
END;
Confirm: PUBLIC PROC [depth: INTEGER, action: ROPE] =
BEGIN
ch: Commander.Handle = GetCommanderHandle[];
in: IO.STREAM = ch.in;
out: IO.STREAM = ch.out;
FOR i: INT IN [0 .. depth) DO out.PutChar['\t] ENDLOOP;
out.PutF["Ready to %g ? ", IO.rope[action]];
WHILE in.GetChar[] # '\n DO NULL ENDLOOP;
END;
NewVisit: PUBLIC ENTRY PROC RETURNS [v: Visit] = {
v ← [visitCount ← visitCount+1];
};
IncrementStepCount: PUBLIC ENTRY PROC [job: Job] = {
ENABLE UNWIND => {};
job.nSteps ← job.nSteps + 1;
};
AddFailedCmd: PUBLIC ENTRY PROC [job: Job, c: Command] = {
ENABLE UNWIND => {};
job.failedSteps ← CONS[c, job.failedSteps];
};
AddCommand: PUBLIC ENTRY PROC [job: Job, cmd: ROPE] = {
ENABLE UNWIND => {};
job.cmds ← job.cmds.Cat[cmd, "\n"];
};
nodes: Table ← MakeNodeTable[];
DestroyGraph: PUBLIC ENTRY PROC = {
ENABLE UNWIND => NULL;
DestroyNode: INTERNAL PROC [data: REF ANY] RETURNS [stop: BOOLFALSE] --RedBlackTree.EachNode-- = {
n: Node = NARROW[data];
IF n.producer # NIL AND n.producer.c # NIL THEN DestroyCmd[n.producer.c];
IF n.producer # NIL THEN n.producer.c ← NIL;
n.producer ← NIL;
n.class ← NIL;
n.props ← NIL;
n.lockedOuts ← NIL;
};
DestroyCmd: INTERNAL PROC [c: Command] = {
RemoveConsumption[c, cmd];
RemoveConsumption[c, data];
WHILE c.makes.first # NIL DO
UnlinkMake[c.makes.first];
ENDLOOP;
c.class ← NIL;
c.foundData ← NIL;
c.missedSources ← NIL;
c.lockedOuts ← NIL;
};
DestroyQueues[];
nodes.EnumerateIncreasing[DestroyNode];
nodes.DestroyTable[];
};
UnlinkMake: INTERNAL PROC [e: Edge] = {
n: Node = e.n;
c: Command = e.c;
IF e.nNext # NIL OR e.nPrev # NIL THEN ERROR;
n.producer ← NIL;
IF e.cNext # NIL THEN e.cNext.cPrev ← e.cPrev ELSE c.makes.last ← e.cPrev;
IF e.cPrev # NIL THEN e.cPrev.cNext ← e.cNext ELSE c.makes.first ← e.cNext;
e.cNext ← e.cPrev ← NIL;
};
SuspectAll: PUBLIC ENTRY PROC [change, remake: BOOL] = {
ENABLE UNWIND => NULL;
stack: Table = NewRefTable[];
PerNode: PROC [data: REF ANY] RETURNS [stop: BOOLFALSE] --RedBlackTree.EachNode-- = {
n: Node = NARROW[data];
IF change THEN SuspectNodeChange[n, stack];
IF remake THEN SuspectProducer[n, stack];
};
nodes.EnumerateIncreasing[PerNode];
};
NewRefTable: PUBLIC PROC RETURNS [table: Table] =
{table ← RedBlackTree.Create[IdGetKey, CompareRefs]};
MakeNodeTable: PUBLIC PROC RETURNS [table: Table] =
{table ← RedBlackTree.Create[IdGetKey, CompareNodes]};
AddNodeToTable: PUBLIC PROC [n: Node, t: Table] =
{t.Insert[n, n]};
NodeInTable: PUBLIC PROC [n: Node, t: Table] RETURNS [BOOL] = {
in: BOOL ← t.Lookup[n] # NIL;
RETURN [in]};
IsRootGoal: PUBLIC PROC [job: Job, n: Node] RETURNS [BOOL] =
{RETURN [NodeInTable[n, job.goals]]};
GetNode: PUBLIC ENTRY PROC [someName: ROPE, class: NodeClass, mayAdd: BOOLTRUE] RETURNS [node: Node] = {
ENABLE UNWIND => NULL;
canonicalName: ROPEIF class # NIL THEN class.CanonizeName[someName] ELSE someName;
IF (node ← NARROW[nodes.Lookup[canonicalName]]) = NIL AND mayAdd THEN {
node ← NEW [NodeRep ← [name: canonicalName, class: class, down: NewMonitorLock[]]];
nodes.Insert[node, node];
}
ELSE IF node = NIL THEN NULL
ELSE IF node.class = NIL THEN node.class ← class
ELSE IF class # NIL AND class # node.class THEN ERROR;
};
Exists: PUBLIC PROC [n: Node] RETURNS [exists: BOOL] =
{exists ← GetCreated[n] # notExistTime};
IdGetKey: PUBLIC PROC [data: REF ANY] RETURNS [REF ANY] --RedBlackTree.GetKey-- =
{RETURN[data]};
CompareNodes: PUBLIC PROC [k, data: REF ANY] RETURNS [Basics.Comparison] --RedBlackTree.Compare-- =
BEGIN
GetKey: PROC [ra: REF] RETURNS[r: ROPE] = {
r ← WITH ra SELECT FROM
n: Node => n.name,
x: ROPE => x,
ENDCASE => ERROR};
k1: ROPE ← GetKey[k];
k2: ROPE ← GetKey[data];
RETURN [k1.Compare[s2: k2, case: FALSE]];
END;
CompareRefs: PUBLIC PROC [k, data: REF ANY] RETURNS [Basics.Comparison] --RedBlackTree.Compare-- = TRUSTED
BEGIN
k1: INTLOOPHOLE[k];
k2: INTLOOPHOLE[data];
RETURN [SELECT k1 FROM
< k2 => less,
= k2 => equal,
> k2 => greater,
ENDCASE => ERROR];
END;
END.