<> <> <> <> <> <> <<1. This is a temporary hack to let us exercise at least some of the Dragon process code on D-machines.>> <<2. Names that start out "Sim..." or "sim..." are part of the simulation environment (SIM), and will be deleted for the Real Dragon Implementation (RDI).>> <<3. There are (intended to be) lots of comments about how things will change for the RDI. Search for SIM and RDI in the comments.>> <> <<1. We should consider splitting this into Process and ProcessPrivate - ajd.>> <<2. This needs much more work on making the simulated processor state look like a real processor.>> <<3. On interrupt enable/disable: note when you return, the enable/disable state reverts to that of the caller (except for EnableInterrupts[] and DisableInterrupts[]); but this is NOT TRUE for INLINES. Thus, there's a very subtle side-effect to commenting out the INLINE on a procedure. Arrgh.>> DIRECTORY DragOps USING [Word, ZerosWord]; SimProcess: CEDAR DEFINITIONS = BEGIN Word: TYPE = DragOps.Word; wordZero: Word = DragOps.ZerosWord; <> <> <> SimLock: TYPE ~ REF SimLockRep; SimLockRep: TYPE ~ MONITORED RECORD []; <> Queue: TYPE = LONG POINTER TO QueueRep; QueueRep: TYPE = RECORD [ busy: Process, -- a GSL that protects the chain chain: Process -- points to the tail of a circular process queue ]; MetaQueue: TYPE = LONG POINTER TO MetaQueueRep; MetaQueueRep: TYPE = Process; emptyMetaQueueRep: MetaQueueRep = NIL; <> MonitorLock: TYPE = LONG POINTER TO MonitorLockRep; MonitorLockRep: TYPE = RECORD [ queue: QueueRep, -- the GQ of waiting processes owner: Process -- the process owning the lock ]; InitializeMonitorLock: PROC [monitorLock: MonitorLock] = TRUSTED INLINE {monitorLock^ _ [queue: [NIL, NIL], owner: NIL]}; Condition: TYPE = LONG POINTER TO ConditionRep; ConditionRep: TYPE = RECORD [ queue: QueueRep, -- the GQ of waiting processes timeout: Ticks, -- the timeout initialization flags: CondFlags -- option flags ]; Ticks: TYPE = CARD; noTimeout: Ticks = 0; Milliseconds: TYPE = CARD; Seconds: TYPE = CARD; CondFlags: TYPE ~ MACHINE DEPENDENT RECORD [ padBitsA: PACKED ARRAY [0..16) OF BOOL, padBitsB: PACKED ARRAY [0..14) OF BOOL, <> abortEnable: BOOL, condRequest: BOOL ]; defaultCondFlags: CondFlags ~ [padBitsA~ALL[FALSE], padBitsB~ALL[FALSE], abortEnable~FALSE, condRequest~FALSE]; InitializeCondition: PROC [condition: Condition, ticks: Ticks] = TRUSTED INLINE { condition^ _ [queue: [NIL, NIL], timeout: ticks, flags: defaultCondFlags] }; MsecToTicks: SAFE PROC [Milliseconds] RETURNS [Ticks]; SecondsToTicks: SAFE PROC [Seconds] RETURNS [Ticks]; TicksToMsec: SAFE PROC [Ticks] RETURNS [Milliseconds]; <> SetTimeout: PROC [condition: Condition, ticks: Ticks] = TRUSTED INLINE {condition.timeout _ IF ticks = noTimeout THEN noTimeout+1 ELSE ticks}; DisableTimeout: PROC [condition: Condition] = TRUSTED INLINE {condition.timeout _ noTimeout}; InterruptCondition: TYPE = LONG POINTER TO InterruptConditionRep; InterruptConditionRep: TYPE = RECORD [queue: QueueRep, timeout: Word, requests: Word]; <> ProcessPtr: TYPE = LONG POINTER TO Process; Process: TYPE = LONG POINTER TO ProcessRep; ProcessRep: TYPE = RECORD [ queue: Queue, -- pointer to queue that this process is waiting for next: Process, -- next process in above circular queue meta: Process, -- next process in ready queue, timeout queue or page fault queue when: Ticks, -- when timeout will occur page: Word, -- page number for fault priority: Priority, -- priority of this process state: ProcessState, -- process state euState: EUstate, -- useful registers in EU lock: MonitorLockRep, -- ML for following fields abortState: AbortState, -- aborting state joinState: JoinState, -- JOIN / Detach state joinCondition: ConditionRep, -- to wait for JOIN rendezvous sim: RefSimProcess -- SIM only ]; RefSimProcess: TYPE ~ REF SimProcessRep; SimProcessRep: TYPE ~ RECORD [ -- SIM only lock: SimLock, awakenEvent: CONDITION, awakened: BOOL, processor: Processor ]; Priority: TYPE = MACHINE DEPENDENT { slothful (0), -- user-level deep background processing (idle) sluggish (1), -- user-level background processing normal (2), -- user-level normal processing perky (3), -- user-level foreground processing nervous (4), -- system-level ?? processing jumpy (5), -- system-level ?? processing excited (6), -- system-level real-time processing hyper (7) -- system-level emergency processing }; ProcessState: TYPE = MACHINE DEPENDENT { free (0), -- process is on free list running (1), -- process is running (assigned to a processor) ready (2), -- process is ready to run (on ready queue) waitingPage (3), -- process is waiting for page fault (on page fault queue) waitingCV (4), -- process is waiting for CV waitingML (5), -- process is waiting for ML waitingICV (6), -- process is waiting for ICV done (7) -- process is done (waiting for Join) (This may be subsumed by JoinState, below ???? ) - ajd }; AbortState: TYPE = MACHINE DEPENDENT { none (0), -- process not requested to abort requested (1), -- process abort requested inhibited (2), -- process abort not allowed & not requested delayed (3) -- process abort requested but not allowed }; JoinState: TYPE ~ MACHINE DEPENDENT { none (0), -- nothing has happened yet exiting (1), -- process has finished, is waiting on its own joinCondition joining (2), -- parent has JOINed and is waiting process's joinCondition joined (3), -- parent has JOINed and retrieved results of process detached (4) -- parent has detached process }; <> EUstateIndex: TYPE = MACHINE DEPENDENT { <> carry (0), -- the carry bit (not really a register) field (1), -- shifter control temp0 (2), -- user aux reg 0 ???? - ajd temp1 (3), -- user aux reg 1 ???? - ajd temp2 (4), -- user aux reg 2 ???? - ajd temp3 (5), -- user aux reg 3 ???? - ajd <> hook (6), -- pointer to the youngest frame saved to memory (a nacho) framesLeft (7) -- frames left before fault occurs }; EUstate: TYPE = ARRAY EUstateIndex OF Word; <> <> Nacho: TYPE = LONG POINTER TO NachoRep; NachoRep: TYPE = RECORD [ link: Nacho, -- link to the next elder frame in the process stack nextPC: Word, -- the continuation PC for the frame nextStatus: Word, -- the continuation Status for the frame nRegs: Word, -- the # of registers saved in this Nacho others: Nacho, -- the link to the area for more saved registers regs: RegArray -- the saved registers (local variables) ]; RegArray: TYPE = ARRAY Reg OF Word; Reg: TYPE = [0..15]; -- Should this be something out of DragOps???? ajd <> Detach: PROC [PROCESS]; <> <> <<= TRUSTED INLINE {>> <<};>> <> SetPriority: SAFE PROC [p: Priority]; <> <<= TRUSTED INLINE {>> <<};>> <> Abort: PROC [Process]; <> CheckForAbort: SAFE PROC; <> DisableAborts: PROC [condition: Condition] = TRUSTED INLINE {condition^.flags.abortEnable _ FALSE}; EnableAborts: PROC [condition: Condition] = TRUSTED INLINE {condition^.flags.abortEnable _ TRUE}; <> Pause: SAFE PROC [ticks: Ticks]; Yield: SAFE PROC = TRUSTED INLINE{ DirectedYield[] }; DirectedYield: UNSAFE PROC [nextState: ProcessState _ ready, nextProcess: Process _ NIL, when: Ticks _ 0]; SetTimeSlice: SAFE PROC [ticks: Ticks]; <> ValidateProcess: PROC [Process]; InvalidProcess: ERROR [process: Process]; <> <> <<>> Processor: TYPE = LONG POINTER TO ProcessorRep; ProcessorRep: TYPE = RECORD [ next: Processor, -- next processor in ring. orders: ProcessorOrders, -- orders for what to do after reschedule (hint only). switchTo: Process, -- if orders = switchToGiven, then switch to this one (hint only). running: Process, -- the process currently being run. sim: RefSimProcessor -- SIM only. ]; RefSimProcessor: TYPE ~ REF SimProcessorRep; SimProcessorRep: TYPE ~ RECORD [ -- SIM only lock: SimLock, interruptsEnabled: BOOL, rescheduleRequested: BOOL, process: Process, -- an aux register processor: Processor -- an aux register ]; ProcessorOrders: TYPE = MACHINE DEPENDENT { reset (0), -- useful during system init (?) noChange (1), -- ignore the reschedule switchToGiven (2), -- switch to process given by processor.switchTo (NIL => to best) panicStop (3), -- save current process, then spin on these orders stopped (4) -- stopped in response to panicStop }; <> RequestKind: TYPE = [0..31]; RequestWordPtr: TYPE = LONG POINTER TO RequestWord; RequestWord: TYPE = PACKED ARRAY RequestKind OF BOOL; nullRequestWord: RequestWord = ALL[FALSE]; IntHandler: TYPE ~ PROC [requestKind: RequestKind]; RegisterIntHandler: SAFE PROC [requestKind: RequestKind, intHandler: IntHandler] RETURNS [old: IntHandler]; <> <<>> END.