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.class.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 ran: BOOLEAN _ FALSE; WHILE StepSim[sim] # noStep DO ran _ TRUE ENDLOOP; IF ran THEN RoseEvents.Notify[event: $EndOfRun, watched: sim, handleAborted: TRUE]; 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 => NULL; switchStep => SwitchStepSim[sim]; otherStep => {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]; 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] = {ReallyPerturb[node, CellToStr[within], within.sim]}; PerturbPort: PUBLIC PROC [cell: Cell, index: CARDINAL] = {ReallyPerturb[cell.interfaceNodes[index], ContainingStr[cell], cell.sim]}; ReallyPerturb: PROC [node: Node, str: Structure, sim: Simulation] = BEGIN IF node.type.simple THEN ERROR; 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; }; }; END; FindExteriorVicinity: PUBLIC PROC [cell: Cell, index: CARDINAL] = BEGIN ReallyFindVicinity[ContainingStr[cell], cell.interfaceNodes[index]]; END; ReallyFindVicinity: PROC [str: Structure, n: Node] = BEGIN IF n.found THEN RETURN; n.found _ TRUE; IF str.firstAffected = notInNodeList THEN ERROR; n.nextAffected _ str.firstAffected; str.firstAffected _ n; 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]; 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]; 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.class.ports[st.index].special AND NotAgg[st.cell] THEN special ELSE general}; StrFindVicinity: PROC [cell: Cell, index: CARDINAL] = BEGIN str: Structure _ NARROW[cell.realCellStuff.state]; this: Node; IF index # noPort THEN ReallyFindVicinity[str, str.insideNodes[index]]; WHILE str.firstPerturbed # NIL DO IF str.firstPerturbed = notInNodeList THEN ERROR; this _ str.firstPerturbed; str.firstPerturbed _ this.nextPerturbed; this.nextPerturbed _ notInNodeList; ReallyFindVicinity[str, this]; ENDLOOP; END; StrMirrorFindVicinity: PROC [cell: Cell, index: CARDINAL] = BEGIN str: Structure _ NARROW[cell.realCellStuff.state]; unmirrored: Cell_ cell.parent; this: Node; IF index # noPort THEN ReallyFindVicinity[str, unmirrored.interfaceNodes[index]]; WHILE str.firstPerturbed # NIL DO IF str.firstPerturbed = notInNodeList THEN ERROR; this _ str.firstPerturbed; str.firstPerturbed _ this.nextPerturbed; this.nextPerturbed _ notInNodeList; ReallyFindVicinity[str, this]; 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]; 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.class.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 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.class.hasASpecialPort AND NotAgg[needed])) THEN LOOP; FOR index: CARDINAL IN [0 .. needed.class.ports.length) DO IF needed.class.ports[index].type.procs.QFromNode # NIL THEN needed.class.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.class.ports.length) DO inside: Node _ needed.interfaceNodes[index]; IF inside.type.procs.NewQ = NIL OR NOT needed.class.ports[index].output THEN LOOP; IF inside.nextAffected = notInNodeList THEN ERROR; IF inside.type.procs.NewQ[inside, SocketToWP[[needed, index], TRUE]] THEN Need2[str, inside, needed]; ENDLOOP; ENDLOOP; IF NOT top THEN FOR index: CARDINAL IN [0 .. innerBorder.class.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.class.hasASpecialPort AND NotAgg[cell] THEN RoseIOHacks.CopyIO[ from: cell.realCellStuff.newIOAsWP, to: cell.realCellStuff.switchIOAsWP, by: cell.class.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]; Need1[str, n, InitUD]; RoseEvents.Notify[event: $NewNodeUD, watched: n, handleAborted: TRUE, arg: NIL]; 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; NotAgg: PROC [cell: Cell] RETURNS [notAgg: BOOL] = INLINE { notAgg _ cell.expansion = Leaf AND CellToStr[cell.parent].mirror # cell}; StrPropUDWork: PROC [str: Structure, innerBorder: Cell, borderNodes: NodeS, top: BOOLEAN] = BEGIN IF NOT top THEN FOR index: CARDINAL IN [0 .. innerBorder.class.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 { Need2[str, inside, innerBorder]; RoseEvents.Notify[event: $NewNodeUD, watched: inside, handleAborted: TRUE, arg: 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.class.hasASpecialPort AND NotAgg[needed])) THEN LOOP; FOR index: CARDINAL IN [0 .. needed.class.ports.length) DO IF needed.class.ports[index].type.procs.UDFromNode # NIL THEN needed.class.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.class.ports.length) DO inside: Node _ needed.interfaceNodes[index]; IF inside.type.procs.NewUD = NIL OR NOT needed.class.ports[index].output THEN LOOP; IF inside.nextAffected = notInNodeList THEN ERROR; IF inside.type.procs.NewUD[inside, SocketToWP[[needed, index], TRUE]] THEN { Need2[str, inside, needed]; RoseEvents.Notify[event: $NewNodeUD, watched: inside, handleAborted: TRUE, arg: needed]}; ENDLOOP; ENDLOOP; IF NOT top THEN FOR index: CARDINAL IN [0 .. innerBorder.class.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]; RoseEvents.Notify[event: $ChangeEarly, watched: n, handleAborted: TRUE]; RoseEvents.Notify[event: $ChangeLate, watched: n, 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.class.ports.length) DO ntp: NodeProcs _ firstNoted.class.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.class.ports.length) DO port: Port _ cell.class.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]; 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.class.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.class.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.class.ioWordCount) DO (o+i)^ _ (n+i)^; ENDLOOP; IF cell.class.hasASpecialPort AND NotAgg[cell] THEN FOR portIndex: CARDINAL IN [0 .. cell.class.ports.length) DO port: Port _ cell.class.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 notAgg: BOOL = NotAgg[cell]; anyDiff _ FALSE; FOR portIndex: CARDINAL IN [0 .. cell.class.ports.length) DO port: Port _ cell.class.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 notAgg AND port.special 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]; 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. RoseRunImpl.mesa Last Edited by: Spreitzer, July 13, 1984 11:20:59 pm PDT PDT Last Edited by: Barth, July 23, 1984 11:43:40 am 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™Kš˜Kšœœœœœœœœœœœœœ'œœ˜²Kšœœ˜*Kšœ˜—K˜šŸœœœ˜$Kš˜Kšœœœ˜Kšœœœœ˜2KšœœBœ˜SKšœ˜—K˜šŸœœœœ˜JKš˜Kšœ˜Kšœ œ˜.Kš œœœœœ ˜DKšœœœœ˜8Kšœœœœ ˜3K˜Kšœ˜—K˜šŸœœœœ˜MKš˜šœ˜ Kšœ œ˜K˜!KšœPœ˜WKšœœ˜—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˜šŸ œœœ˜5Kšœ5˜5—K˜šŸ œœœœ˜8KšœK˜K—K˜šŸ œœ0˜CKš˜Kšœœœ˜šœ$œ˜,Kšœ$œœ˜1Kšœ(˜(Kšœ˜šœ"œ˜*Kšœ&œœ˜3Kšœ*˜*Kšœ˜K˜—K˜—Kšœ˜—K˜šŸœœœœ˜AKš˜KšœD˜DKšœ˜—K˜šŸœœ˜4Kš˜Kšœ œœ˜Kšœ œ˜Kšœ#œœ˜0K˜#K˜šœ%œœ˜9Kšœ2œœO˜‹KšœGœ˜LKšœ˜—šœ$œœ˜8Kšœ2œœO˜‹KšœGœ˜LKšœHœ˜MKšœ˜—šœ%œœ˜9KšœHœ˜MKšœ˜—Kšœ˜—K˜šŸ œœœ˜7Kš œœ'œœ œ ˜^—K˜šŸœœœ˜5Kš˜Kšœœ˜2K˜ Kšœœ1˜Gšœœ˜!Kšœ$œœ˜1Kšœ˜Kšœ(˜(Kšœ#˜#K˜Kšœ˜—Kšœ˜—K˜šŸœœœ˜;Kš˜Kšœœ˜2K˜K˜ Kšœœ;˜Qšœœ˜!Kšœ$œœ˜1Kšœ˜Kšœ(˜(Kšœ#˜#K˜Kšœ˜—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šœ˜Kšœ˜—Kšœ˜—K˜šŸœ  œ˜)Kš˜Kšœœ˜2Kš œœœœœœ˜YKšœ˜—K˜šŸœ  œ˜/Kš˜Kšœœ˜2Kšœ;œ˜BKšœ˜—K˜šŸ œœ>œ˜ZKš˜šœœ˜šœœœ'˜?Kšœ"˜"Kšœœœœ˜*KšœAœœ!˜oKšœ˜——šœœ˜K˜Kšœœœ˜%Kšœ2˜2Kšœ0˜0Kšœœ˜%Kšœ%œœœœœœ˜ršœœœ"˜:Kšœ2œœjœ˜­Kšœ˜—Kšœ4˜4šœœœ"˜:K˜,Kš œœœœ"œœ˜RKšœ%œœ˜2Kšœ<œœ˜eKšœ˜—Kšœ˜—šœœ˜šœœœ'˜?Kšœ"˜"Kšœœœœ˜/KšœEœ˜LKšœ˜——Kšœ˜—K˜šŸ œœ˜.Kš˜šœœœ˜GKšœ#˜#Kšœ$˜$Kšœ˜Kšœ8˜8Kš œ œ œ œ œ˜=—Kšœœœ ˜Kšœ˜—K˜šŸœ  œ˜)šœœœ˜)Kšœœ˜#Kšœ#œœ)˜V——K˜šŸ œ  œ˜*Kš˜Kšœœ˜2šœ-œœ˜@Kšœœœ˜ Kšœœœ˜9Kšœ˜Kšœ@œœ˜PKšœ˜—Kšœ˜—K˜šŸ œ  œ˜*Kš˜Kšœœ˜2Kš œœœœœœ˜ZKšœ˜—K˜šŸœ  œ˜0Kš˜KšœœEœ˜`Kšœ˜—K˜š Ÿœœœ œœ˜;Kšœœ'˜I—K˜šŸ œœ>œ˜[Kš˜šœœ˜šœœœ'˜?Kšœ"˜"Kšœœœœ˜+šœBœœ˜QKšœ ˜ KšœEœ˜]—Kšœ˜——šœœ˜K˜Kšœœœ˜%Kšœ2˜2Kšœ0˜0Kšœ œ˜&Kšœ&œœœœœœ˜sšœœœ"˜:Kšœ3œœkœ˜―Kšœ˜—K˜5šœœœ"˜:K˜,Kš œœœœ"œœ˜SKšœ%œœ˜2šœ=œœ˜LKšœ˜KšœEœ˜Y—Kšœ˜—Kšœ˜—šœœ˜šœœœ'˜?Kšœ"˜"Kšœ œœœ˜0KšœFœ˜MKšœ˜——Kšœ˜—K˜šŸ œ  œ˜+Kš˜Kšœœ˜2Kšœœ˜šœ-œœ˜@Kšœœœ˜ Kšœ œ˜Kšœœœ˜9KšœBœ˜HKšœAœ˜Gšœ%œœ˜9šœ7˜=K˜Q—Kšœ˜—šœ$œœ˜8šœ7˜=K˜Q—Kšœ˜—šœ%œœ˜9šœ7˜=K˜Q—Kšœ˜—Kšœ˜—Kšœœ˜šœœœ˜;Kšœœœ˜)K˜*Kšœ3˜3šœœœ&˜>Kšœ:˜:šœ˜šœ˜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šœœœ!˜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šœ˜—…—`D‚φ