DIRECTORY IO, List, OrderedSymbolTableRef, Rope, RoseEvents, RoseIOHacks, RoseRun, RoseTypes; RoseRunImpl: CEDAR PROGRAM IMPORTS RoseEvents, RoseIOHacks, RoseTypes EXPORTS RoseRun, RoseTypes = BEGIN OPEN RoseTypes; stop: PUBLIC BOOLEAN _ FALSE; notInStrList: PUBLIC Structure _ NEW [StructureRep]; notInCellList: PUBLIC Cell _ NEW [CellRep]; notInNodeList: PUBLIC Node _ NEW [NodeRep]; StrEvals: PUBLIC EvalProcs _ [ InitQ: StrInitQ, PropQ: StrPropQ, InitUD: StrInitUD, PropUD: StrPropUD, FinalUD: StrFinalUD, EvalSimple: StrSimple, FindVicinity: StrFindVicinity ]; StrMirrorEvals: PUBLIC EvalProcs _ [ InitQ: StrInitQ, PropQ: StrMirrorPropQ, InitUD: StrInitUD, PropUD: StrMirrorPropUD, FinalUD: StrFinalUD, EvalSimple: StrMirrorSimple, FindVicinity: StrMirrorFindVicinity ]; SocketToWP: PUBLIC PROC [s: Socket, useBryant: BOOL _ FALSE] RETURNS [wp: WordPtr] = TRUSTED BEGIN wp _ (IF useBryant THEN s.cell.realCellStuff.switchIOAsWP ELSE s.cell.realCellStuff.newIOAsWP) + s.cell.type.ports[s.index].firstWord; END; CellToStr: PUBLIC PROC [cell: Cell] RETURNS [str: Structure] = BEGIN WHILE (IF cell.realCellStuff = NIL THEN TRUE ELSE IF cell.realCellStuff.state = NIL THEN TRUE ELSE NOT ISTYPE[cell.realCellStuff.state, Structure]) DO cell _ cell.parent ENDLOOP; RETURN [NARROW[cell.realCellStuff.state]]; END; Run: PUBLIC PROC [sim: Simulation] = BEGIN WHILE StepSim[sim] # noStep DO IF stop THEN SIGNAL Stop[msg: "Stopped", data: sim]; ENDLOOP; END; Next: PUBLIC PROC [sim: Simulation] RETURNS [stepType: RoseRun.StepType] = BEGIN topStr: Structure; topStr _ NARROW[sim.root.realCellStuff.state]; IF sim.switched AND topStr.schedFirst # NIL THEN RETURN [otherStep]; IF sim.firstPerturbedStr # NIL THEN RETURN [switchStep]; IF topStr.schedFirst # NIL THEN RETURN [otherStep]; stepType _ noStep; END; StepSim: PUBLIC PROC [sim: Simulation] RETURNS [stepType: RoseRun.StepType] = BEGIN SELECT stepType _ Next[sim] FROM noStep => { wasSettled: BOOL _ sim.wasSettled; sim.wasSettled _ TRUE; IF NOT wasSettled THEN RoseEvents.Notify[event: $Settled, watched: sim, handleAborted: TRUE]; }; switchStep => { sim.wasSettled _ FALSE; SwitchStepSim[sim]; }; otherStep => { sim.wasSettled _ FALSE; sim.root.realCellStuff.evals.EvalSimple[sim.root]; sim.switched _ FALSE; }; ENDCASE => ERROR; END; SwitchStepSim: PROC [sim: Simulation] = BEGIN str: Structure; sim.firstWasPerturbedStr _ sim.firstPerturbedStr; sim.firstPerturbedStr _ NIL; FOR str _ sim.firstWasPerturbedStr, str.nextWasPerturbed WHILE str # NIL DO IF str = notInStrList THEN ERROR; IF str.nextPerturbed = notInStrList THEN ERROR; str.nextWasPerturbed _ str.nextPerturbed; str.nextPerturbed _ notInStrList; ENDLOOP; FOR str _ sim.firstWasPerturbedStr, str.nextWasPerturbed WHILE str # NIL DO IF str.container.realCellStuff.evals # StrEvals THEN ERROR; StrFindVicinity[str.container, noPort, FALSE]; ENDLOOP; FOR str _ sim.firstWasPerturbedStr, str.nextWasPerturbed WHILE str # NIL DO IF NOT str.container.realCellStuff.initQed THEN { str.container.realCellStuff.initQed _ TRUE; StrInitQ[str.container]} ENDLOOP; FOR str _ sim.firstWasPerturbedStr, str.nextWasPerturbed WHILE str # NIL DO IF NOT str.container.realCellStuff.propQed THEN { str.container.realCellStuff.propQed _ TRUE; StrPropQWork[str, IF str.mirror = NIL THEN str.container ELSE str.mirror, str.insideNodes, TRUE]} ENDLOOP; FOR str _ sim.firstWasPerturbedStr, str.nextWasPerturbed WHILE str # NIL DO IF NOT str.container.realCellStuff.initUDed THEN { str.container.realCellStuff.initUDed _ TRUE; StrInitUD[str.container]} ENDLOOP; FOR str _ sim.firstWasPerturbedStr, str.nextWasPerturbed WHILE str # NIL DO IF NOT str.container.realCellStuff.propUDed THEN { str.container.realCellStuff.propUDed _ TRUE; StrPropUDWork[str, IF str.mirror = NIL THEN str.container ELSE str.mirror, str.insideNodes, TRUE]} ENDLOOP; FOR str _ sim.firstWasPerturbedStr, str.nextWasPerturbed WHILE str # NIL DO StrFinalUD[str.container]; str.container.realCellStuff.initQed _ str.container.realCellStuff.propQed _ str.container.realCellStuff.initUDed _ str.container.realCellStuff.propUDed _ FALSE; ENDLOOP; sim.switched _ TRUE; END; PerturbNode: PUBLIC PROC [node: Node, within: Cell, evenIfInput: BOOL _ FALSE] = {ReallyPerturb[node, CellToStr[within], within.sim, within, evenIfInput]}; PerturbPort: PUBLIC PROC [cell: Cell, index: CARDINAL, evenIfInput: BOOL _ FALSE] = {ReallyPerturb[cell.interfaceNodes[index], ContainingStr[cell], cell.sim, cell, evenIfInput]}; ReallyPerturb: PROC [node: Node, str: Structure, sim: Simulation, cell: Cell, evenIfInput: BOOL _ FALSE] = BEGIN IF node.type.simple THEN ERROR; IF node.isInput AND NOT evenIfInput THEN RETURN; IF node.nextPerturbed = notInNodeList THEN { IF str.firstPerturbed = notInNodeList THEN ERROR; node.nextPerturbed _ str.firstPerturbed; str.firstPerturbed _ node; IF str.nextPerturbed = notInStrList THEN { IF sim.firstPerturbedStr = notInStrList THEN ERROR; str.nextPerturbed _ sim.firstPerturbedStr; sim.firstPerturbedStr _ str; }; RoseEvents.Notify[event: $Perturbed, watched: node, handleAborted: TRUE, arg: cell]; }; END; FindExteriorVicinity: PUBLIC PROC [cell: Cell, index: CARDINAL, evenIfInput: BOOL _ FALSE] = BEGIN ReallyFindVicinity[ContainingStr[cell], cell.interfaceNodes[index], evenIfInput, [cell, index]]; END; ReallyFindVicinity: PROC [str: Structure, n: Node, evenIfInput: BOOL, from: Socket] = BEGIN IF n.found THEN RETURN; IF n.isInput AND NOT evenIfInput THEN RETURN; n.found _ TRUE; IF str.firstAffected = notInNodeList THEN ERROR; n.nextAffected _ str.firstAffected; str.firstAffected _ n; RoseEvents.Notify[$Found, n, TRUE, from.cell]; FOR sl: SocketList _ n.readers, sl.rest WHILE sl # NIL DO IF sl.first.cell.realCellStuff.evals.FindVicinity # NIL THEN sl.first.cell.realCellStuff.evals.FindVicinity[sl.first.cell, sl.first.index, evenIfInput]; sl.first.cell.realCellStuff.affectedFlags[read][Specialty[sl.first]] _ TRUE; ENDLOOP; FOR sl: SocketList _ n.bidirs, sl.rest WHILE sl # NIL DO IF sl.first.cell.realCellStuff.evals.FindVicinity # NIL THEN sl.first.cell.realCellStuff.evals.FindVicinity[sl.first.cell, sl.first.index, evenIfInput]; sl.first.cell.realCellStuff.affectedFlags[read][Specialty[sl.first]] _ TRUE; sl.first.cell.realCellStuff.affectedFlags[write][Specialty[sl.first]] _ TRUE; ENDLOOP; FOR sl: SocketList _ n.writers, sl.rest WHILE sl # NIL DO sl.first.cell.realCellStuff.affectedFlags[write][Specialty[sl.first]] _ TRUE; ENDLOOP; END; Specialty: PROC [st: Socket] RETURNS [sy: Speciality] = {sy _ IF st.cell.type.ports[st.index].special AND NotAgg[st.cell] THEN special ELSE general}; NotAgg: PROC [cell: Cell] RETURNS [notAgg: BOOL] = INLINE {notAgg _ cell.expansion = Leaf AND CellToStr[cell.parent].mirror # cell}; StrFindVicinity: PROC [cell: Cell, portIndex: CARDINAL, evenIfInput: BOOL] = BEGIN str: Structure _ NARROW[cell.realCellStuff.state]; this: Node; IF portIndex # noPort THEN ReallyFindVicinity[str, str.insideNodes[portIndex], evenIfInput, [str.mirror, portIndex]]; WHILE str.firstPerturbed # NIL DO IF str.firstPerturbed = notInNodeList THEN ERROR; this _ str.firstPerturbed; str.firstPerturbed _ this.nextPerturbed; this.nextPerturbed _ notInNodeList; ReallyFindVicinity[str, this, this.isInput, [NIL, LAST[CARDINAL]]]; ENDLOOP; END; StrMirrorFindVicinity: PROC [cell: Cell, portIndex: CARDINAL, evenIfInput: BOOL] = BEGIN str: Structure _ NARROW[cell.realCellStuff.state]; unmirrored: Cell_ cell.parent; this: Node; IF portIndex # noPort THEN ReallyFindVicinity[str, unmirrored.interfaceNodes[portIndex], evenIfInput, [unmirrored, portIndex]]; WHILE str.firstPerturbed # NIL DO IF str.firstPerturbed = notInNodeList THEN ERROR; this _ str.firstPerturbed; str.firstPerturbed _ this.nextPerturbed; this.nextPerturbed _ notInNodeList; ReallyFindVicinity[str, this, this.isInput, [NIL, LAST[CARDINAL]]]; ENDLOOP; END; Need1: PROC [str: Structure, n: Node, also: CellProc] = BEGIN FOR sl: SocketList _ n.writers, sl.rest WHILE sl # NIL DO IF sl.first.cell.realCellStuff.nextNeeded = notInCellList THEN BEGIN IF str.firstNeeded = notInCellList THEN ERROR; sl.first.cell.realCellStuff.nextNeeded _ str.firstNeeded; str.firstNeeded _ sl.first.cell; IF also # NIL THEN also[sl.first.cell]; END; ENDLOOP; FOR sl: SocketList _ n.bidirs, sl.rest WHILE sl # NIL DO IF sl.first.cell.realCellStuff.nextNeeded = notInCellList THEN BEGIN IF str.firstNeeded = notInCellList THEN ERROR; sl.first.cell.realCellStuff.nextNeeded _ str.firstNeeded; str.firstNeeded _ sl.first.cell; IF also # NIL THEN also[sl.first.cell]; END; ENDLOOP; FOR sl: SocketList _ n.readers, sl.rest WHILE sl # NIL DO IF sl.first.cell.realCellStuff.nextNeeded = notInCellList THEN BEGIN IF str.firstNeeded = notInCellList THEN ERROR; sl.first.cell.realCellStuff.nextNeeded _ str.firstNeeded; str.firstNeeded _ sl.first.cell; IF also # NIL THEN also[sl.first.cell]; END; ENDLOOP; END; Need2: PROC [str: Structure, n: Node, except: Cell] = BEGIN FOR sl: SocketList _ n.readers, sl.rest WHILE sl # NIL DO IF sl.first.cell.realCellStuff.nextNeeded = notInCellList AND sl.first.cell # except AND (sl.first.cell.realCellStuff.affectedFlags[write][special] OR sl.first.cell.realCellStuff.affectedFlags[write][general]) THEN BEGIN IF str.firstNeeded = notInCellList THEN ERROR; sl.first.cell.realCellStuff.nextNeeded _ str.firstNeeded; str.firstNeeded _ sl.first.cell; END; ENDLOOP; FOR sl: SocketList _ n.bidirs, sl.rest WHILE sl # NIL DO IF sl.first.cell.realCellStuff.nextNeeded = notInCellList AND sl.first.cell # except THEN BEGIN IF str.firstNeeded = notInCellList THEN ERROR; sl.first.cell.realCellStuff.nextNeeded _ str.firstNeeded; str.firstNeeded _ sl.first.cell; END; ENDLOOP; END; InitQ: CellProc--PROC [cell: Cell]-- = { IF NOT cell.realCellStuff.initQed THEN { cell.realCellStuff.initQed _ TRUE; IF cell.realCellStuff.evals.InitQ # NIL THEN cell.realCellStuff.evals.InitQ[cell]}}; StrInitQ: CellProc--PROC [cell: Cell]-- = BEGIN str: Structure _ NARROW[cell.realCellStuff.state]; FOR n: Node _ str.firstAffected, n.nextAffected WHILE n # NIL DO IF n = notInNodeList THEN ERROR; IF n.type.procs.InitQ # NIL THEN n.type.procs.InitQ[n]; RoseEvents.Notify[event: $NewNodeQ, watched: n, handleAborted: TRUE, arg: NIL]; Need1[str, n, InitQ]; ENDLOOP; END; StrPropQ: CellProc--PROC [cell: Cell]-- = BEGIN str: Structure _ NARROW[cell.realCellStuff.state]; StrPropQWork[str, IF str.mirror = NIL THEN cell ELSE str.mirror, str.insideNodes, FALSE]; END; StrMirrorPropQ: CellProc--PROC [cell: Cell]-- = BEGIN str: Structure _ NARROW[cell.realCellStuff.state]; StrPropQWork[str, cell.parent, cell.parent.interfaceNodes, FALSE]; END; StrPropQWork: PROC [str: Structure, innerBorder: Cell, borderNodes: NodeS, top: BOOLEAN] = BEGIN IF NOT top THEN FOR index: CARDINAL IN [0 .. innerBorder.type.ports.length) DO inside: Node _ borderNodes[index]; IF inside.type.procs.NewQ = NIL THEN LOOP; IF inside.type.procs.NewQ[inside, SocketToWP[[innerBorder, index], TRUE]] THEN { RoseEvents.Notify[event: $NewNodeQ, watched: inside, handleAborted: TRUE, arg: innerBorder]; Need2[str, inside, innerBorder]; }; ENDLOOP; WHILE str.firstNeeded # NIL DO needed: Cell _ str.firstNeeded; IF needed = notInCellList THEN ERROR; str.firstNeeded _ needed.realCellStuff.nextNeeded; needed.realCellStuff.nextNeeded _ notInCellList; needed.realCellStuff.initQed _ FALSE; IF (needed.realCellStuff.evals.PropQ = NIL) AND (NOT (needed.type.hasASpecialPort AND NotAgg[needed])) THEN LOOP; FOR index: CARDINAL IN [0 .. needed.type.ports.length) DO IF needed.type.ports[index].type.procs.QFromNode # NIL THEN needed.type.ports[index].type.procs.QFromNode[needed.interfaceNodes[index], SocketToWP[[needed, index], TRUE]]; ENDLOOP; PropInner[needed, needed.realCellStuff.evals.PropQ]; FOR index: CARDINAL IN [0 .. needed.type.ports.length) DO inside: Node _ needed.interfaceNodes[index]; IF inside.type.procs.NewQ = NIL OR NOT needed.type.ports[index].output THEN LOOP; IF inside.nextAffected = notInNodeList THEN ERROR; IF inside.type.procs.NewQ[inside, SocketToWP[[needed, index], TRUE]] THEN { RoseEvents.Notify[event: $NewNodeQ, watched: inside, handleAborted: TRUE, arg: needed]; Need2[str, inside, needed]; }; ENDLOOP; ENDLOOP; IF NOT top THEN FOR index: CARDINAL IN [0 .. innerBorder.type.ports.length) DO inside: Node _ borderNodes[index]; IF inside.type.procs.QFromNode = NIL THEN LOOP; inside.type.procs.QFromNode[inside, SocketToWP[[innerBorder, index], TRUE]]; ENDLOOP; END; PropInner: PROC [cell: Cell, prop: CellProc] = BEGIN IF cell.type.hasASpecialPort AND NotAgg[cell] THEN RoseIOHacks.CopyIO[ from: cell.realCellStuff.newIOAsWP, to: cell.realCellStuff.switchIOAsWP, by: cell.type.ports, what: [inputs: none, outputs: forward, bidirs: forward], specials: TRUE, generals: FALSE, simples: FALSE, drive: NIL]; IF prop # NIL THEN prop[cell]; END; InitUD: CellProc--PROC [cell: Cell]-- = { IF NOT cell.realCellStuff.initUDed THEN { cell.realCellStuff.initUDed _ TRUE; IF cell.realCellStuff.evals.InitUD # NIL THEN cell.realCellStuff.evals.InitUD[cell]}}; StrInitUD: CellProc--PROC [cell: Cell]-- = BEGIN str: Structure _ NARROW[cell.realCellStuff.state]; FOR n: Node _ str.firstAffected, n.nextAffected WHILE n # NIL DO IF n = notInNodeList THEN ERROR; IF n.type.procs.InitUD # NIL THEN n.type.procs.InitUD[n]; RoseEvents.Notify[event: $NewNodeUD, watched: n, handleAborted: TRUE, arg: NIL]; Need1[str, n, InitUD]; ENDLOOP; END; StrPropUD: CellProc--PROC [cell: Cell]-- = BEGIN str: Structure _ NARROW[cell.realCellStuff.state]; StrPropUDWork[str, IF str.mirror = NIL THEN cell ELSE str.mirror, str.insideNodes, FALSE]; END; StrMirrorPropUD: CellProc--PROC [cell: Cell]-- = BEGIN StrPropUDWork[NARROW[cell.realCellStuff.state], cell.parent, cell.parent.interfaceNodes, FALSE]; END; StrPropUDWork: PROC [str: Structure, innerBorder: Cell, borderNodes: NodeS, top: BOOLEAN] = BEGIN IF NOT top THEN FOR index: CARDINAL IN [0 .. innerBorder.type.ports.length) DO inside: Node _ borderNodes[index]; IF inside.type.procs.NewUD = NIL THEN LOOP; IF inside.type.procs.NewUD[inside, SocketToWP[[innerBorder, index], TRUE]] THEN { RoseEvents.Notify[event: $NewNodeUD, watched: inside, handleAborted: TRUE, arg: innerBorder]; Need2[str, inside, innerBorder]; }; ENDLOOP; WHILE str.firstNeeded # NIL DO needed: Cell _ str.firstNeeded; IF needed = notInCellList THEN ERROR; str.firstNeeded _ needed.realCellStuff.nextNeeded; needed.realCellStuff.nextNeeded _ notInCellList; needed.realCellStuff.initUDed _ FALSE; IF (needed.realCellStuff.evals.PropUD = NIL) AND (NOT (needed.type.hasASpecialPort AND NotAgg[needed])) THEN LOOP; FOR index: CARDINAL IN [0 .. needed.type.ports.length) DO IF needed.type.ports[index].type.procs.UDFromNode # NIL THEN needed.type.ports[index].type.procs.UDFromNode[needed.interfaceNodes[index], SocketToWP[[needed, index], TRUE]]; ENDLOOP; PropInner[needed, needed.realCellStuff.evals.PropUD]; FOR index: CARDINAL IN [0 .. needed.type.ports.length) DO inside: Node _ needed.interfaceNodes[index]; IF inside.type.procs.NewUD = NIL OR NOT needed.type.ports[index].output THEN LOOP; IF inside.nextAffected = notInNodeList THEN ERROR; IF inside.type.procs.NewUD[inside, SocketToWP[[needed, index], TRUE]] THEN { RoseEvents.Notify[event: $NewNodeUD, watched: inside, handleAborted: TRUE, arg: needed]; Need2[str, inside, needed]; }; ENDLOOP; ENDLOOP; IF NOT top THEN FOR index: CARDINAL IN [0 .. innerBorder.type.ports.length) DO inside: Node _ borderNodes[index]; IF inside.type.procs.UDFromNode = NIL THEN LOOP; inside.type.procs.UDFromNode[inside, SocketToWP[[innerBorder, index], TRUE]]; ENDLOOP; END; StrFinalUD: CellProc--PROC [cell: Cell]-- = BEGIN str: Structure _ NARROW[cell.realCellStuff.state]; firstNoted, next: Cell _ NIL; FOR n: Node _ str.firstAffected, n.nextAffected WHILE n # NIL DO IF n = notInNodeList THEN ERROR; n.found _ FALSE; IF n.type.procs.NewVal # NIL THEN n.type.procs.NewVal[n]; theActivityReport.node _ n; theActivityReport.socket _ [NIL, noPort]; RoseEvents.Notify[event: $ChangeEarly, watched: n, handleAborted: TRUE]; RoseEvents.Notify[event: $ChangeLate, watched: n, handleAborted: TRUE]; RoseEvents.Notify[event: $SwitchChanged, arg: theActivityReport, handleAborted: TRUE]; FOR sl: SocketList _ n.readers, sl.rest WHILE sl # NIL DO IF sl.first.cell.realCellStuff.nextNoted = notInCellList THEN {sl.first.cell.realCellStuff.nextNoted _ firstNoted; firstNoted _ sl.first.cell}; ENDLOOP; FOR sl: SocketList _ n.bidirs, sl.rest WHILE sl # NIL DO IF sl.first.cell.realCellStuff.nextNoted = notInCellList THEN {sl.first.cell.realCellStuff.nextNoted _ firstNoted; firstNoted _ sl.first.cell}; ENDLOOP; FOR sl: SocketList _ n.writers, sl.rest WHILE sl # NIL DO IF sl.first.cell.realCellStuff.nextNoted = notInCellList THEN {sl.first.cell.realCellStuff.nextNoted _ firstNoted; firstNoted _ sl.first.cell}; ENDLOOP; ENDLOOP; str.firstAffected _ NIL; FOR firstNoted _ firstNoted, next WHILE firstNoted # NIL DO IF firstNoted = notInCellList THEN ERROR; next _ firstNoted.realCellStuff.nextNoted; firstNoted.realCellStuff.nextNoted _ notInCellList; FOR index: CARDINAL IN [0 .. firstNoted.type.ports.length) DO ntp: NodeProcs _ firstNoted.type.ports[index].type.procs; IF ntp.ValFromNode # NIL THEN ntp.ValFromNode[ firstNoted.interfaceNodes[index], SocketToWP[[firstNoted, index], TRUE]]; IF SocketIsSpecial[[firstNoted, index]] AND ntp.UDFromNode # NIL THEN ntp.UDFromNode[ firstNoted.interfaceNodes[index], SocketToWP[[firstNoted, index], TRUE]]; ENDLOOP; IF firstNoted.realCellStuff.evals.FinalUD # NIL THEN firstNoted.realCellStuff.evals.FinalUD[firstNoted]; IF firstNoted.realCellStuff.affectedFlags[read][special] THEN ScheduleCell[firstNoted]; IF (firstNoted.realCellStuff.affectedFlags[read][general] OR firstNoted.realCellStuff.affectedFlags[read][special]) AND firstNoted.realCellStuff.evals.ValsChanged # NIL THEN ValsChanged[firstNoted, str]; firstNoted.realCellStuff.affectedFlags _ ALL[ALL[FALSE]]; ENDLOOP; END; ValsChanged: PROC [cell: Cell, str: Structure] = BEGIN NewToOld[cell]; cell.realCellStuff.evals.ValsChanged[cell !UNWIND => [] _ ReallyCleanUpAfterModify[cell: cell, str: str, outputsOnly: TRUE, blindly: FALSE, mayRescheduleSelf: TRUE, simples: TRUE, generals: FALSE, specials: TRUE]]; [] _ ReallyCleanUpAfterModify[cell: cell, str: str, outputsOnly: TRUE, blindly: FALSE, mayRescheduleSelf: TRUE, simples: TRUE, generals: FALSE, specials: TRUE]; END; StrSimple: CellProc--PROC [cell: Cell]-- = BEGIN str: Structure _ NARROW[cell.realCellStuff.state]; IF str.running THEN ERROR ELSE str.running _ TRUE; BEGIN ENABLE UNWIND => {str.running _ FALSE}; FOR portIndex: CARDINAL IN [0 .. cell.type.ports.length) DO port: Port _ cell.type.ports[portIndex]; IF NOT port.type.simple THEN LOOP; TRUSTED BEGIN Distribute[ cell.realCellStuff.newIOAsWP + port.firstWord, str.insideNodes[portIndex], NIL, str]; END; ENDLOOP; RunStr[str]; END; str.running _ FALSE; END; StrMirrorSimple: CellProc--PROC [cell: Cell]-- = {ERROR Error["Attempt to evaluate mirror's other", cell]}; ValueChanged: PUBLIC PROC [node: Node] = BEGIN IF node.type.simple THEN ERROR; PerturbNode[node, node.cellIn, TRUE]; RoseEvents.Notify[event: $ChangeEarly, watched: node, handleAborted: TRUE]; RoseEvents.Notify[event: $ChangeLate, watched: node, handleAborted: TRUE]; END; Distribute: PROC [base: WordPtr, fromNode: Node, fromCell: Cell, str: Structure] = BEGIN DoDest: PROC [dest: Socket] = BEGIN target: Cell _ dest.cell; targPort: Port _ target.type.ports[dest.index]; sourceWP: WordPtr _ base; destWP: WordPtr; IF target = NIL THEN ERROR; TRUSTED BEGIN destWP _ target.realCellStuff.newIOAsWP + targPort.firstWord; END; FOR j: CARDINAL IN [0 .. targPort.wordCount) DO TRUSTED BEGIN destWP^ _ sourceWP^; sourceWP _ sourceWP + 1; destWP _ destWP + 1; END; ENDLOOP; IF target = fromCell THEN NULL ELSE IF target = str.mirror THEN { IF NOT str.running THEN { parentCell: Cell _ str.container; parentStr: Structure _ ContainingStr[parentCell]; Distribute[base: SocketToWP[[parentCell, dest.index]], fromNode: parentCell.interfaceNodes[dest.index], fromCell: parentCell, str: parentStr]; ScheduleAllup[parentCell, parentStr]; }; } ELSE ScheduleAllup[target, str]; END; abort: BOOLEAN _ FALSE; IF fromNode.type.procs.SetNode # NIL THEN fromNode.type.procs.SetNode[fromNode, base]; FOR dests: SocketList _ fromNode.readers, dests.rest WHILE dests # NIL DO DoDest[dests.first] ENDLOOP; FOR dests: SocketList _ fromNode.bidirs, dests.rest WHILE dests # NIL DO DoDest[dests.first] ENDLOOP; FOR dests: SocketList _ fromNode.writers, dests.rest WHILE dests # NIL DO DoDest[dests.first] ENDLOOP; RoseEvents.Notify[event: $ChangeEarly, watched: fromNode, handleAborted: TRUE]; RoseEvents.Notify[event: $ChangeLate, watched: fromNode, handleAborted: TRUE]; END; ScheduleStep: PROC [cell: Cell, str: Structure] = BEGIN IF cell.realCellStuff.schedNext # notInCellList THEN RETURN; cell.realCellStuff.schedNext _ NIL; IF str.schedLast = NIL THEN str.schedFirst _ cell ELSE str.schedLast.realCellStuff.schedNext _ cell; str.schedLast _ cell; RoseEvents.Notify[event: $Schedule, watched: cell, handleAborted: TRUE]; END; ScheduleAllup: PROC [cell: Cell, str: Structure] = BEGIN IF cell.parent # NIL THEN DO IF cell.realCellStuff.schedNext # notInCellList THEN RETURN; cell.realCellStuff.schedNext _ NIL; IF str.schedLast = NIL THEN str.schedFirst _ cell ELSE str.schedLast.realCellStuff.schedNext _ cell; str.schedLast _ cell; RoseEvents.Notify[event: $Schedule, watched: cell, handleAborted: TRUE]; IF str.running THEN RETURN; IF (cell _ str.container).parent = NIL THEN RETURN; str _ ContainingStr[cell]; ENDLOOP; END; NewToOld: PUBLIC PROC [cell: Cell] = TRUSTED BEGIN n: WordPtr _ cell.realCellStuff.newIOAsWP; o: WordPtr _ cell.realCellStuff.oldIOAsWP; FOR i: CARDINAL IN [0 .. cell.type.ioWordCount) DO (o+i)^ _ (n+i)^; ENDLOOP; END; PreSimple: PUBLIC PROC [cell: Cell] = TRUSTED BEGIN n: WordPtr _ cell.realCellStuff.newIOAsWP; o: WordPtr _ cell.realCellStuff.oldIOAsWP; FOR i: CARDINAL IN [0 .. cell.type.ioWordCount) DO (o+i)^ _ (n+i)^; ENDLOOP; IF cell.type.hasASpecialPort AND NotAgg[cell] THEN FOR portIndex: CARDINAL IN [0 .. cell.type.ports.length) DO port: Port _ cell.type.ports[portIndex]; IF port.special THEN { n: WordPtr _ cell.realCellStuff.newIOAsWP + port.firstWord; s: WordPtr _ cell.realCellStuff.switchIOAsWP + port.firstWord; FOR i: CARDINAL IN [0 .. port.wordCount) DO (n+i)^ _ (s+i)^; ENDLOOP; }; ENDLOOP; END; RunStr: PROC [str: Structure] = BEGIN WHILE str.schedFirst # NIL DO cell: Cell; IF str.schedFirst = notInCellList THEN ERROR; IF stop THEN SIGNAL Stop[msg: "Stopped", data: str]; cell _ PickFromSchedule[str]; IF cell.realCellStuff.evals.EvalSimple # NIL THEN BEGIN PreSimple[cell]; cell.realCellStuff.evals.EvalSimple[cell !UNWIND => { [] _ ReallyCleanUpAfterModify[cell, str, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE]; ScheduleAllup[cell, str]; }]; [] _ ReallyCleanUpAfterModify[cell, str, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE]; RoseEvents.Notify[event: $Eval, watched: cell, handleAborted: TRUE]; END; ENDLOOP; END; PickFromSchedule: PROC [str: Structure] RETURNS [cell: Cell] = BEGIN abort: BOOLEAN _ FALSE; cell _ str.schedFirst; IF (str.schedFirst _ cell.realCellStuff.schedNext) = NIL THEN str.schedLast _ NIL; cell.realCellStuff.schedNext _ notInCellList; RoseEvents.Notify[event: $Schedule, watched: cell, handleAborted: TRUE]; IF str.schedFirst = NIL THEN RETURN; RoseEvents.Notify[event: $Schedule, watched: str.schedFirst, handleAborted: TRUE]; END; ReallyCleanUpAfterModify: PROC [cell: Cell, str: Structure, outputsOnly, blindly, mayRescheduleSelf, simples, generals, specials: BOOLEAN] RETURNS [anyDiff: BOOLEAN] = BEGIN anyDiff _ FALSE; FOR portIndex: CARDINAL IN [0 .. cell.type.ports.length) DO port: Port _ cell.type.ports[portIndex]; node: Node _ cell.interfaceNodes[portIndex]; diff: BOOLEAN _ FALSE; newWP: WordPtr; oldWP: WordPtr; IF (outputsOnly AND NOT port.output) THEN LOOP; IF NOT (IF port.type.simple THEN simples ELSE IF port.special AND NotAgg[cell] THEN specials ELSE generals) THEN LOOP; TRUSTED BEGIN newWP _ cell.realCellStuff.newIOAsWP + port.firstWord; oldWP _ cell.realCellStuff.oldIOAsWP + port.firstWord; END; IF blindly THEN diff _ TRUE ELSE BEGIN IF port.special AND (NOT port.type.simple) AND NotAgg[cell] AND (port.type.procs.ComputeQ # NIL) THEN port.type.procs.ComputeQ[node, newWP]; FOR i: CARDINAL IN [0 .. port.wordCount) DO TRUSTED BEGIN IF newWP^ # oldWP^ THEN {diff _ TRUE; EXIT}; newWP _ newWP + 1; oldWP _ oldWP + 1; END; ENDLOOP; END; IF diff THEN TRUSTED BEGIN anyDiff _ TRUE; theActivityReport.node _ node; theActivityReport.socket _ node.visible _ [cell, portIndex]; IF port.type.simple THEN { Distribute[ cell.realCellStuff.newIOAsWP + port.firstWord, node, IF NOT mayRescheduleSelf THEN cell ELSE NIL, str]; RoseEvents.Notify[event: $SimpleChanged, watched: NIL, handleAborted: TRUE, arg: theActivityReport]; } ELSE { ReallyPerturb[node: node, str: str, sim: cell.sim, cell: cell]; RoseEvents.Notify[event: $NewSpecialSwitchInstructions, watched: NIL, handleAborted: TRUE, arg: theActivityReport]; }; END; ENDLOOP; END; theActivityReport: RoseRun.ActivityReport _ NEW [RoseRun.ActivityReportRep]; ScheduleCell: PUBLIC PROC [cell: Cell] = {ScheduleAllup[cell, ContainingStr[cell]]}; AllowToModify: PUBLIC PROC [cell: Cell, modifier: RoseRun.ModifyProc, blindly, mayRescheduleSelf: BOOLEAN _ FALSE] = BEGIN str: Structure _ ContainingStr[cell]; subtle: BOOL _ FALSE; IF NOT blindly THEN NewToOld[cell]; subtle _ modifier[cell !UNWIND => BEGIN [] _ ReallyCleanUpAfterModify[cell, str, FALSE, blindly, mayRescheduleSelf, TRUE, TRUE, TRUE]; END]; [] _ ReallyCleanUpAfterModify[cell, str, FALSE, blindly, mayRescheduleSelf, TRUE, TRUE, TRUE]; IF subtle THEN ScheduleAllup[cell, str]; END; notInCellList.name _ "notInCellList"; notInNodeList.name _ "notInNodeList"; END. LRoseRunImpl.mesa Last Edited by: Spreitzer, October 7, 1984 4:27:18 pm PDT PDT Last Edited by: Barth, April 25, 1984 9:54:24 am PST Last Edited by: Gasbarro, July 17, 1984 4:24:09 pm PDT AllowToModify: PUBLIC PROC [cell: Cell, modifier: RoseRun.ModifyProc, blindly, mayRescheduleSelf: BOOLEAN _ FALSE] = BEGIN ReallyAllowToModify: RoseRun.ModifyProc--PROC [cell: Cell] RETURNS [subtle: BOOLEAN _ FALSE]-- = BEGIN --GetStrLock[str];-- IF NOT blindly THEN NewToOld[theCell]; subtle _ modifier[theCell !UNWIND => BEGIN subtle _ ReallyCleanUpAfterModify[theCell, str, FALSE, blindly, mayRescheduleSelf, TRUE, TRUE, TRUE]; --ReleaseStrLock[str];-- END]; IF subtle THEN ScheduleStep[theCell, str]; subtle _ subtle OR ReallyCleanUpAfterModify[theCell, str, FALSE, blindly, mayRescheduleSelf, TRUE, TRUE, TRUE]; --ReleaseStrLock[str];-- END; theCell: Cell _ cell; str: Structure _ NIL; IF cell.parent = NIL THEN [] _ modifier[theCell] ELSE IF (str _ CellToStr[cell.parent]).container.parent = NIL THEN [] _ ReallyAllowToModify[NIL] ELSE AllowToModify[str.container, ReallyAllowToModify, FALSE]; END; Κρ˜Jšœ™J™=J™4J™6Icode˜KšΟk œœQ˜]K˜šΠbx œœœ˜Kšœ#˜*Kšœ˜—K˜Kšœœ ˜K˜Kšœœœœ˜K˜Kšœœ œ˜4Kšœœœ ˜+Kšœœœ ˜+K˜šœ œ˜K˜K˜K˜K˜K˜K˜K˜K˜—K˜šœœ˜$K˜K˜K˜K˜K˜Kšœ˜K˜#K˜—K˜š Οn œœœœœœ˜TKšœ˜ Kšœœ œ#œH˜†Kšœ˜—K˜šŸ œœœœ˜>Kš˜Kšœœœœœœœœœœœœœ'œœ˜²Kšœœ˜*Kšœ˜—K˜šŸœœœ˜$Kš˜šœ˜Kšœœœ!˜4Kšœ˜—Kšœ˜—K˜šŸœœœœ˜JKš˜Kšœ˜Kšœ œ˜.Kš œœœœœ ˜DKšœœœœ˜8Kšœœœœ ˜3K˜Kšœ˜—K˜šŸœœœœ˜MKš˜šœ˜ šœ ˜ Kšœ œ˜"Kšœœ˜Kšœœ œAœ˜]Kšœ˜—˜Kšœœ˜K˜K˜—šœ˜Kšœœ˜Kšœ2˜2Kšœœ˜Kšœ˜—Kšœœ˜—Kšœ˜—K˜šŸ œœ˜'Kš˜K˜Kšœ1˜1Kšœœ˜šœ6œœ˜KKšœœœ˜!Kšœ"œœ˜/Kšœ)˜)Kšœ!˜!Kšœ˜—šœ6œœ˜KKšœ.œœ˜;Kšœ'œ˜.Kšœ˜—šœ6œœ˜Kšœœ%œ˜1Kšœ&œ˜+Kšœ˜—Kšœ˜—šœ6œœ˜Kšœœ%œ˜1Kšœ&œ˜+Kš œœœœœœ˜a—Kšœ˜—šœ6œœ˜Kšœœ&œ˜2Kšœ'œ˜,Kšœ˜—Kšœ˜—šœ6œœ˜Kšœœ&œ˜2Kšœ'œ˜,Kš œœœœœœ˜b—Kšœ˜—šœ6œœ˜KKšœ˜Kšœšœ˜ Kšœ˜—Kšœœ˜Kšœ˜—K˜š Ÿ œœœ)œœ˜PKšœJ˜J—K˜š Ÿ œœœœœœ˜SKšœ^˜^—K˜šŸ œœHœœ˜jKš˜Kšœœœ˜Kš œœœ œœ˜0šœ$œ˜,Kšœ$œœ˜1Kšœ(˜(Kšœ˜šœ"œ˜*Kšœ&œœ˜3Kšœ*˜*Kšœ˜K˜—KšœCœ ˜TK˜—Kšœ˜—K˜š Ÿœœœœœœ˜\Kš˜Kšœ`˜`Kšœ˜—K˜šŸœœ(œ˜UKš˜Kšœ œœ˜Kš œ œœ œœ˜-Kšœ œ˜Kšœ#œœ˜0K˜#K˜Kšœœ ˜.šœ%œœ˜9Kšœ2œœ\˜˜KšœGœ˜LKšœ˜—šœ$œœ˜8Kšœ2œœ\˜˜KšœGœ˜LKšœHœ˜MKšœ˜—šœ%œœ˜9KšœHœ˜MKšœ˜—Kšœ˜—K˜šŸ œœœ˜7Kš œœ&œœ œ ˜]—K˜š Ÿœœœ œ˜9Kšœ œ'˜J—K˜šŸœœœœ˜LKš˜Kšœœ˜2K˜ Kšœœ[˜ušœœ˜!Kšœ$œœ˜1Kšœ˜Kšœ(˜(Kšœ#˜#Kšœ-œœœ˜CKšœ˜—Kšœ˜—K˜šŸœœœœ˜RKš˜Kšœœ˜2K˜K˜ Kšœœe˜šœœ˜!Kšœ$œœ˜1Kšœ˜Kšœ(˜(Kšœ#˜#Kšœ-œœœ˜CKšœ˜—Kšœ˜—K˜šŸœœ,˜7Kš˜šœ%œœ˜9šœ8˜>Kš˜Kšœ!œœ˜.Kšœ9˜9K˜ Kšœœœ˜'Kšœ˜—Kšœ˜—šœ$œœ˜8šœ8˜>Kš˜Kšœ!œœ˜.Kšœ9˜9K˜ Kšœœœ˜'Kšœ˜—Kšœ˜—šœ%œœ˜9šœ8˜>Kš˜Kšœ!œœ˜.Kšœ9˜9K˜ Kšœœœ˜'Kšœ˜—Kšœ˜—Kšœ˜—K˜šŸœœ*˜5Kš˜šœ%œœ˜9š œ8œœ<œ<˜ΦKš˜Kšœ!œœ˜.Kšœ9˜9K˜ Kšœ˜—Kšœ˜—šœ$œœ˜8šœ8œ˜YKš˜Kšœ!œœ˜.Kšœ9˜9K˜ Kšœ˜—Kšœ˜—Kšœ˜—K˜šŸœ Οcœ˜(šœœœ˜(Kšœœ˜"Kšœ"œœ(˜T——K˜šŸœ  œ˜)Kš˜Kšœœ˜2šœ-œœ˜@Kšœœœ˜ Kšœœœ˜7Kšœ?œœ˜OKšœ˜Kšœ˜—Kšœ˜—K˜šŸœ  œ˜)Kš˜Kšœœ˜2Kš œœœœœœ˜YKšœ˜—K˜šŸœ  œ˜/Kš˜Kšœœ˜2Kšœ;œ˜BKšœ˜—K˜šŸ œœ>œ˜ZKš˜šœœ˜šœœœ&˜>Kšœ"˜"Kšœœœœ˜*šœAœœ˜PKšœDœ˜\Kšœ ˜ Kšœ˜—Kšœ˜——šœœ˜K˜Kšœœœ˜%Kšœ2˜2Kšœ0˜0Kšœœ˜%Kšœ%œœœœœœ˜qšœœœ!˜9Kšœ1œœiœ˜«Kšœ˜—Kšœ4˜4šœœœ!˜9K˜,Kš œœœœ!œœ˜QKšœ%œœ˜2šœ<œœ˜KKšœDœ˜WKšœ˜Kšœ˜—Kšœ˜—Kšœ˜—šœœ˜šœœœ&˜>Kšœ"˜"Kšœœœœ˜/KšœEœ˜LKšœ˜——Kšœ˜—K˜šŸ œœ˜.Kš˜šœœœ˜FKšœ#˜#Kšœ$˜$Kšœ˜Kšœ8˜8Kš œ œ œ œ œ˜=—Kšœœœ ˜Kšœ˜—K˜šŸœ  œ˜)šœœœ˜)Kšœœ˜#Kšœ#œœ)˜V——K˜šŸ œ  œ˜*Kš˜Kšœœ˜2šœ-œœ˜@Kšœœœ˜ Kšœœœ˜9Kšœ@œœ˜PKšœ˜Kšœ˜—Kšœ˜—K˜šŸ œ  œ˜*Kš˜Kšœœ˜2Kš œœœœœœ˜ZKšœ˜—K˜šŸœ  œ˜0Kš˜KšœœEœ˜`Kšœ˜—K˜šŸ œœ>œ˜[Kš˜šœœ˜šœœœ&˜>Kšœ"˜"Kšœœœœ˜+šœBœœ˜QKšœEœ˜]Kšœ ˜ K˜—Kšœ˜——šœœ˜K˜Kšœœœ˜%Kšœ2˜2Kšœ0˜0Kšœ œ˜&Kšœ&œœœœœœ˜ršœœœ!˜9Kšœ2œœjœ˜­Kšœ˜—K˜5šœœœ!˜9K˜,Kš œœœœ!œœ˜RKšœ%œœ˜2šœ=œœ˜LKšœEœ˜XKšœ˜Kšœ˜—Kšœ˜—Kšœ˜—šœœ˜šœœœ&˜>Kšœ"˜"Kšœ œœœ˜0KšœFœ˜MKšœ˜——Kšœ˜—K˜šŸ œ  œ˜+Kš˜Kšœœ˜2Kšœœ˜šœ-œœ˜@Kšœœœ˜ Kšœ œ˜Kšœœœ˜9Kšœ˜Kšœœ ˜)KšœBœ˜HKšœAœ˜GKšœPœ˜Všœ%œœ˜9šœ7˜=K˜Q—Kšœ˜—šœ$œœ˜8šœ7˜=K˜Q—Kšœ˜—šœ%œœ˜9šœ7˜=K˜Q—Kšœ˜—Kšœ˜—Kšœœ˜šœœœ˜;Kšœœœ˜)K˜*Kšœ3˜3šœœœ%˜=Kšœ9˜9šœ˜šœ˜Kšœ!˜!Kšœ œ˜'——šœ&œ˜@šœ˜Kšœ!˜!Kšœ œ˜'——Kšœ˜—Kšœ*œœ4˜hšœ6˜8Kšœ˜—šœ8œ8œ.˜¨Kšœ˜"—Kšœ)œœœ˜9Kšœ˜—Kšœ˜—K˜šŸ œœ˜0Kš˜K˜˜)KšœœEœ œœ œ œ œ˜¬—Kš œAœ œœ œ œ œ˜ Kšœ˜—K˜šŸ œ  œ˜*Kš˜Kšœœ˜2š œ œœœœ˜2Kšœœœœ˜-šœ œœ˜;Kšœ(˜(šœœœœ˜"Kšœ˜ ˜ Kšœ.˜.K˜Kšœ˜K˜—Kšœ˜—Kšœ˜—K˜ Kšœ˜—Kšœœ˜Kšœ˜—K˜šŸœ  œ˜0Kšœœ4˜:—K˜šŸ œœœ˜(Kš˜Kšœœœ˜Kšœœ˜%KšœEœ˜KKšœDœ˜JKšœ˜—K˜šŸ œœB˜RKš˜šŸœœ˜Kš˜Kšœ˜Kšœ/˜/Kšœ˜Kšœ˜šœ œœœ˜Kšœ˜ Kšœ=˜=Kšœ˜—šœœœ˜/š˜Kš˜K˜K˜K˜Kšœ˜—Kšœ˜—Kšœœ˜šœœœ˜"šœœ œ˜Kšœ!˜!Kšœ1˜1KšœŽ˜ŽKšœ%˜%K˜—K˜—Kšœ˜ Kšœ˜—Kšœœœ˜Kšœœœ-˜Všœ2œ œ˜IKšœœ˜—šœ1œ œ˜HKšœœ˜—šœ2œ œ˜IKšœœ˜—KšœIœ˜OKšœHœ˜NKšœ˜—K˜šŸ œœ˜1Kš˜Kšœ.œœ˜˜>šœœœ˜+K˜Kšœ˜—K˜—Kšœ˜——Kšœ˜—K˜šŸœœ˜Kš˜šœœ˜Kšœ ˜ Kšœ œœ˜-Kšœœœ!˜4Kšœ˜šœ'œ˜1Kš˜K˜šœ*œ˜5Kš œ)œœœœœœ˜OKšœ˜Kšœ˜—Kš œ)œœœœœœ˜OKšœ>œ˜DKšœ˜—Kšœ˜—Kšœ˜—K˜šŸœœœ˜>Kš˜Kšœœœ˜K˜Kšœ3œœœ˜RK˜-KšœBœ˜HKšœœœœ˜$KšœLœ˜RKšœ˜—K˜š Ÿœœdœœ œ˜§Kš˜Kšœ œ˜šœ œœ˜;K˜(Kšœ,˜,Kšœœœ˜K˜K˜Kš œœœœœ˜/Kšœœœœ œœœœ œ œœ˜všœ˜ Kšœ6˜6Kšœ6˜6Kšœ˜—Kšœ œ˜šœ˜ Kšœœœœœœœ'˜Œšœœœ˜+š˜Kš˜Kšœœ œœ˜,Kšœ˜Kšœ˜Kšœ˜—Kšœ˜—Kšœ˜—šœ˜ Kšœ˜ Kšœ œ˜K˜Kšœ<˜<šœ˜šœ˜šœ ˜ Kšœ.˜.Kšœ˜Kš œœœœœ˜,K˜—Kšœ2œœ˜dK˜—šœ˜Kšœ?˜?KšœAœœ˜sK˜——Kšœ˜—Kšœ˜—Kšœ˜—K˜Kšœ,œ˜LK˜šŸ œœœ˜(Kšœ+˜+—K˜š Ÿ œœœHœœ˜tKš˜K˜%Kšœœœ˜Kšœœ œ˜#šœœ˜!Kš˜Kš œ)œœœœ˜^Kšœ˜—Kš œ)œœœœ˜^Kšœœ˜(Kšœ˜—K˜š Ÿ œœœHœœ™tKš™šŸœ 7œ™`Kš™Kš ™Kšœœ œ™&šœœ™$Kš™Kš œ0œœœœ™eKš ™Kšœ™—Kšœœ™*Kš œœ(œœœœ™oKš ™Kšœ™—K™K™Kšœœ™Kšœœœ™0Kš œœ3œœœ™`Kšœ3œ™>Kšœ™—K˜K˜%K˜%K˜Kšœ˜—…—e‰O