ThymeMain.mesa
Copyright © 1985, 1986 by Xerox Corporation. All rights reserved.
Last Edited by:
Last Edited by: Jacobi June 10, 1986 6:37:00 pm PDT
Christian LeCocq February 4, 1987 6:12:06 pm PST
Pradeep Sindhu March 19, 1986 11:26:37 pm PST
Sweetsun Chen, April 26, 1986 4:59:00 pm PST
Christian Jacobi, June 10, 1986 6:35:10 pm PDT
DIRECTORY
BasicTime USING [Now],
CommandTool USING [Run],
Core USING [CellType],
FileNames USING [CurrentWorkingDirectory],
FS USING [Error],
IO USING [PutF, rope],
MessageWindow USING [Append],
Process USING [Detach, GetPriority, Priority, priorityBackground, SetPriority],
RefText USING [New],
Rope USING [Equal, Find, FromRefText, IsEmpty, ROPE, Substr],
ThymeGlobals USING [Aborted, Bomb, CircuitRec, CleanUp, DefineCircuit, DumpAll, Error, ErrWarnSummary, fileNameStackSeq, fileStackSeq, function, functionTable, FuncTableBlk, Handle, keys, MakePlotList, MakePrintList, maxInclude, maxLog, maxPlots, maxPrints, model, modFuncPtr, modelTable, ModelTableBlk, nameBlk, namePtr, Next, NodeRec, OpenInputFile, Output, PlotSeq, PrintHole, PrintSeq, PutMsgLine, RunIt, SearchKey, SetICs, TopoAnalysis, Variables, WorstNodeLog],
ViewerClasses USING [Viewer],
ViewerTools USING [SetContents];
ThymeMain: CEDAR MONITOR
IMPORTS
BasicTime,
CommandTool,
FileNames,
FS,
IO,
MessageWindow,
Process,
RefText,
Rope,
ThymeGlobals,
ViewerTools
EXPORTS
ThymeGlobals
={ OPEN ThymeGlobals;
NormalRun: PUBLIC PROC[handle: Handle, background, fork: BOOLTRUE]= {
IF handle = NIL THEN RETURN;
IF handle.stage=idle AND handle.simulation=NIL THEN {
curPriority: Process.Priority = Process.GetPriority[];
IF background THEN Process.SetPriority[Process.priorityBackground];
handle.stage ← input;
handle.outer.inhibitDestroy ← TRUE;
IF fork THEN {
handle.simulation ← FORK Simulate[NIL, handle];
TRUSTED {Process.Detach[handle.simulation]};
}
ELSE {
handle.simulation ← NIL;
Simulate[NIL, handle];
};
Process.SetPriority[curPriority];
}
ELSE MessageWindow.Append[message: "Previous simulation has not finished yet.", clearFirst: TRUE];
}; -- NormalRun
BatchRun: PUBLIC PROC[handle: Handle, wDir, inputFile: Rope.ROPENIL, background, fork: BOOLTRUE]= {
IF handle = NIL OR inputFile = NIL THEN RETURN;
IF wDir = NIL THEN wDir ← FileNames.CurrentWorkingDirectory[];
ViewerTools.SetContents[handle.wDir, wDir];
ViewerTools.SetContents[handle.input, inputFile];
NormalRun[handle, background, fork];
IF handle.simulation # NIL THEN TRUSTED {JOIN handle.simulation};
}; -- BatchRun
Simulate: PUBLIC PROC[cell: Core.CellType, handle: Handle]= {
ENABLE {
Aborted => GOTO stop;
ABORTED => {handle.vars.canned ← TRUE; GOTO dumpStop};
FS.Error => {
handle.msgStream.PutF["%g\nProgram stopped.\n", IO.rope[error.explanation]];
GOTO stop;
};
};
theRoot: namePtr ← NEW[nameBlk ← [name: "Main Circuit", details: NEW[CircuitRec← []]] ];
gndNodeName: namePtr ← NEW[nameBlk ← [name: "Gnd", details: NEW[NodeRec] ] ];
Process.SetPriority[Process.priorityBackground];
InitVars[handle];
OpenInputFile[handle];
Next[handle];
libraries
WHILE handle.vars.item=name DO
IF Canned[handle] THEN GOTO stop;
IF SearchKey[handle]=libraryKey THEN AddLibrary[handle] ELSE EXIT;
ENDLOOP;
circuit definition
IF handle.vars.item=name AND SearchKey[handle]=circuitKey THEN {
DefineCircuit[handle: handle, cktRoot: theRoot, gndNodeName: gndNodeName]; -- may signal Aborted
}
ELSE Error[handle, 820, TRUE];
IF handle.vars.item=slash AND handle.vars.errCount <= 0 THEN {
Next[handle];
Output[handle, theRoot, 0];
};
explode
IF handle.vars.item#semi THEN Error[handle, 800,, FALSE]
ELSE IF handle.vars.errCount <= 0 THEN {
NextStage[handle];
Bomb[handle, theRoot, gndNodeName]; -- may signal Aborted
Next[handle];
IF handle.vars.item=plus THEN {Next[handle]; PrintHole[handle]};
};
analyze
IF handle.vars.errCount <= 0 THEN {
NextStage[handle];
TopoAnalysis[handle];
IF Canned[handle] THEN GOTO stop;
};
run
IF handle.vars.errCount <= 0 THEN {
NextStage[handle];
WHILE handle.vars.item=name DO
OPEN handle.vars;
key: keys ← SearchKey[handle];
Next[handle];
SELECT key FROM
runKey=> {
lastTime ← RunIt[handle];
IF NOT Canned[handle] THEN PutMsgLine[handle, "Done."];
};
printKey=> MakePrintList[handle];
plotKey => MakePlotList[handle];
icKey => SetICs[handle];
dumpKey => IF ~ForcedDump[handle] THEN DumpAll[handle, lastTime];
checkPointKey=> {
IF item=leftB THEN Next[handle] ELSE Error[handle, 801];
IF item=number THEN {
Next[handle]
}
ELSE Error[handle, 809, FALSE];
IF item=rightB THEN Next[handle] ELSE Error[handle, 802];
}
ENDCASE=> GOTO err1;
IF item=eof THEN EXIT;
IF item=semi THEN Next[handle] ELSE Error[handle, 800,, FALSE];
REPEAT
err1=> Error[handle, 821, TRUE];
ENDLOOP;
}; -- run
IF ForcedDump[handle] THEN DumpAll[handle, handle.vars.lastTime];
ErrWarnSummary[handle];
killPlot[]
GOTO stop;
EXITS
dumpStop=> {
DumpAll[handle, handle.vars.lastTime];
handle.msgStream.PutF["Last state is dumped in the dump file."];
CleanIt[handle];
};
stop=> CleanIt[handle];
}; -- Simulate
EnterModels: PUBLIC ENTRY PROC[entry: ModelTableBlk]= {
ENABLE UNWIND => NULL;
FOR m: LIST OF REF ModelTableBlk ← modelTable, m.rest UNTIL m=NIL DO
IF Rope.Equal[m.first.name, entry.name] THEN {
m.first^ ← entry;
RETURN;
};
ENDLOOP;
modelTable ← CONS[NEW[ModelTableBlk← entry], modelTable];
}; -- EnterModels
EnterFunctions: PUBLIC ENTRY PROC[entry: FuncTableBlk]= {
ENABLE UNWIND => NULL;
FOR f: LIST OF REF FuncTableBlk ← functionTable, f.rest UNTIL f=NIL DO
IF Rope.Equal[f.first.name, entry.name] THEN {
f.first^ ← entry;
RETURN;
};
ENDLOOP;
functionTable ← CONS[NEW[FuncTableBlk← entry], functionTable];
}; -- EnterFunctions
entry procs
FindModel: PUBLIC ENTRY PROC[name: Rope.ROPE] RETURNS[REF ModelTableBlk]= {
ENABLE UNWIND => NULL;
FOR m: LIST OF REF ModelTableBlk ← modelTable, m.rest UNTIL m=NIL DO
IF Rope.Equal[m.first.name, name] THEN RETURN[m.first];
ENDLOOP;
RETURN[NIL];
}; -- FindModel
FindFunction: PUBLIC ENTRY PROC[name: Rope.ROPE]
RETURNS[REF FuncTableBlk]= {
ENABLE UNWIND => NULL;
FOR f: LIST OF REF FuncTableBlk ← functionTable, f.rest UNTIL f=NIL DO
IF Rope.Equal[f.first.name, name] THEN RETURN[f.first];
ENDLOOP;
RETURN[NIL];
}; -- FindFunction
ResetCheckPoint: PUBLIC ENTRY PROC[handle: Handle]= {
ENABLE UNWIND => NULL;
handle.vars.checkPoint← FALSE };
Canned: PUBLIC ENTRY PROC[handle: Handle] RETURNS[BOOL]= {
ENABLE UNWIND => NULL;
RETURN[handle.vars.canned]};
ForcedDump: PUBLIC ENTRY PROC[handle: Handle] RETURNS[BOOL]= {
ENABLE UNWIND => NULL;
RETURN[handle.vars.forcedDump]};
CheckPoint: PUBLIC ENTRY PROC[handle: Handle] RETURNS[BOOL]= {
ENABLE UNWIND => NULL;
RETURN[handle.vars.checkPoint]};
ShowDetails: PUBLIC ENTRY PROC[handle: Handle] RETURNS[BOOL]= {
ENABLE UNWIND => NULL;
RETURN[handle.showTimeStep]};
EchoInput: PUBLIC ENTRY PROC[handle: Handle] RETURNS[BOOL]= {
ENABLE UNWIND => NULL;
RETURN[handle.echoInput]};
SaveAll: PUBLIC ENTRY PROC[handle: Handle] RETURNS[BOOL]= {
ENABLE UNWIND => NULL;
RETURN[handle.saveAllData]};
StopIt: PUBLIC ENTRY PROC[handle: Handle]= {
ENABLE UNWIND => NULL;
IF handle # NIL THEN {
IF handle.vars # NIL THEN {
handle.vars.forcedDump← FALSE;
handle.vars.canned← TRUE;
};
AbortCheckPoint[handle];
};
}; -- StopIt
DumpIt: PUBLIC ENTRY PROC[handle: Handle]= {
ENABLE UNWIND => NULL;
IF handle # NIL THEN {
IF handle.vars # NIL THEN {
handle.vars.forcedDump← TRUE;
handle.vars.canned← TRUE;
};
AbortCheckPoint[handle];
};
}; -- DumpIt
ToggleShowDetails: PUBLIC ENTRY PROC[handle: Handle]= {
ENABLE UNWIND => NULL;
handle.showTimeStep← ~handle.showTimeStep;
}; -- ToggleShowDetails
ToggleEchoInput: PUBLIC ENTRY PROC[handle: Handle]= {
ENABLE UNWIND => NULL;
handle.echoInput← ~handle.echoInput;
}; -- ToggleEchoInput
ToggleSaveAll: PUBLIC ENTRY PROC[handle: Handle]= {
ENABLE UNWIND => NULL;
handle.saveAllData ← ~handle.saveAllData;
}; -- ToggleSaveAll
NextStage: PUBLIC ENTRY PROC[handle: Handle]= {
ENABLE UNWIND => NULL;
SELECT handle.stage FROM
input, bomb, topo => handle.stage ← SUCC[handle.stage];
run => handle.vars.runState ← (handle.vars.runState + 1) MOD 4;
ENDCASE => MessageWindow.Append[message: "*** Weird 'NextStage'", clearFirst: TRUE];
}; -- NextStage
PeriodicSetCheckPoint: ENTRY PROC[handle: Handle]= {
ENABLE UNWIND => NULL;
WHILE handle # NIL DO
ENABLE ABORTED => EXIT;
WAIT handle.checkPointCV;
IF handle # NIL THEN IF handle.vars # NIL THEN handle.vars.checkPoint ← TRUE ELSE EXIT;
ENDLOOP;
IF handle # NIL THEN TRUSTED {Process.SetTimeout[@handle.checkPointCV, PrincOps.NoTimeout]};
}; -- PeriodicSetCheckPoint
CleanIt: ENTRY PROC[handle: Handle]= {
ENABLE UNWIND => NULL;
CleanUp[handle];
}; -- CleanIt
AbortCheckPoint: INTERNAL PROC[handle: Handle]= {
IF handle = NIL THEN RETURN;
IF handle.stage=run AND handle.checkProcess # NIL THEN {
TRUSTED {Process.Abort[LOOPHOLE[handle.checkProcess, UNSPECIFIED]]};
handle.checkProcess← NIL;
};
}; -- AbortCheckPoint
AddLibrary: PROC[handle: Handle]= {
if the name of the library is not in {MosModels, StdFunctions, Level2Model} then run the program in the command tool
Next[handle];
IF handle.vars.item=leftB THEN Next[handle] ELSE Error[handle, 801, TRUE];
IF handle.vars.item=name THEN {
originalName, nameRoot, errMsg: Rope.ROPE;
dotPosition: INT;
originalName← Rope.FromRefText[handle.vars.newString];
dotPosition← Rope.Find[originalName, "."];
nameRoot← IF dotPosition=-1 THEN originalName
ELSE Rope.Substr[originalName, 0, dotPosition-1];
IF NOT (Rope.Equal[nameRoot, "MosModels", FALSE] OR
Rope.Equal[nameRoot, "StdFunctions", FALSE] OR
Rope.Equal[nameRoot, "Level2Model", FALSE]) THEN {
[errMsg, ] ← CommandTool.Run[originalName];
IF NOT errMsg.IsEmpty[] THEN PutMsgLine[handle, errMsg];
};
Next[handle];
}
ELSE Error[handle, 804, TRUE];
IF handle.vars.item=rightB THEN Next[handle] ELSE Error[handle, 802, FALSE];
IF handle.vars.item=semi THEN Next[handle] ELSE Error[handle, 800, FALSE];
}; -- AddLibrary
InitVars: PROC[handle: Handle]= {
handle.vars← NEW[Variables← [ ]];
{OPEN handle.vars;
simTime ← BasicTime.Now[];
line ← RefText.New[256];
newString ← RefText.New[256];
line.length ← 0;
newString.length ← 0;
fileStack ← NEW[fileStackSeq[maxInclude]];
FOR i: NAT IN [0..maxInclude) DO fileStack[i] ← NIL ENDLOOP;
fileNameStack ← NEW[fileNameStackSeq[maxInclude]];
FOR i: NAT IN [0..maxInclude) DO fileNameStack[i] ← NIL ENDLOOP;
prints ← NEW[PrintSeq[maxPrints]];
FOR i: NAT IN [0..maxPrints) DO prints[i] ← [] ENDLOOP;
plots ← NEW[PlotSeq[maxPlots]];
FOR i: NAT IN [0..maxPlots) DO plots[i] ← [] ENDLOOP;
worstNodeLog ← NEW[WorstNodeLog[maxLog]];
FOR i: NAT IN [0..maxLog) DO worstNodeLog[i] ← []; ENDLOOP;
};
}; -- InitVars
}.
CHANGE LOG
Wilhelm, April 27, 1982 4:07 PM
Barth, 7-May-82 14:41:52 PDT
Chen, April 19, 1983 6:45 PM, changed the version name for openSysWindow.
Barth, July 11, 1983 12:46 PM
Chen, June 12, 1984 11:37:19 am PDT, cedarized.
Chen, May 15, 1985 5:23:49 pm PDT, Thyme viewer is inhibited from being destroyed by user when simulation is running.
Chen, July 22, 1985 8:09:51 pm PDT, => Cedar6.0.
Chen, November 24, 1985 2:57:05 pm PST, as suggested by Pradeep, changed NormalRun, BatchRun, and Simulate to allow client to choose whether to fork and whether to run in background.
Christian Jacobi, June 10, 1986 6:35:28 pm PDT, Changed Simulate to always run in background; (ignoring the interface's option not run in background).