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}; SecureProcess: TYPE ~ RECORD [ key: ProcessKey, -- matches key in ProcessRep index: CARD -- index in process table ]; ProcessKey: TYPE ~ CARD; -- RDI: change this to CARD64 ???? ProcessPtr: TYPE ~ LONG POINTER TO Process; Process: TYPE ~ LONG POINTER TO ProcessRep; ProcessRep: TYPE ~ RECORD [ secure: SecureProcess, -- denotes this ProcessRep 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 lock: MonitorLockRep, -- ML for following fields abortState: AbortState, -- aborting state joinState: JoinState, -- JOIN / Detach state joinCondition: ConditionRep, -- to wait for JOIN rendezvous euState: EUstate, -- useful registers in EU 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 }; AbortState: TYPE ~ MACHINE DEPENDENT { none (0), -- process not requested to abort inhibited (1), -- process abort not allowed requested (2), -- process abort allowed & 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 [SecureProcess]; SetPriority: PROC [p: Priority]; Abort: PROC [SecureProcess]; CheckForAbort: PROC; EnableAborts: PROC [condition: Condition] ~ TRUSTED INLINE {condition^.flags.abortEnable _ TRUE}; DisableAborts: PROC [condition: Condition] ~ TRUSTED INLINE {condition^.flags.abortEnable _ FALSE}; InhibitAborts: PROC [inhibit: BOOL _ TRUE] RETURNS [wasInhibited: BOOL]; Pause: PROC [ticks: Ticks]; Yield: PROC ~ TRUSTED INLINE{ DirectedYield[] }; DirectedYield: UNSAFE PROC [nextState: ProcessState _ ready, nextProcess: Process _ NIL, when: Ticks _ 0]; SetTimeSlice: PROC [ticks: Ticks]; ValidateProcess: PROC [SecureProcess]; InvalidProcess: ERROR [secureProcess: SecureProcess]; ProcessorPtr: TYPE ~ LONG POINTER TO Processor; 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 { noChange (0), -- ignore the reschedule stopped (1), -- stopped in response to panicStop switchToGiven (2), -- switch to process given by processor.switchTo (NIL => to best) panicStop (3), -- come to panic stop restart (4) -- restart after panic stop }; 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: PROC [requestKind: RequestKind, intHandler: IntHandler] RETURNS [old: IntHandler]; END. SimProcess.mesa Copyright c 1984, 1985, 1986 by Xerox Corporation. All rights reserved. Russ Atkinson (RRA) September 11, 1986 1:40:57 pm PDT Carl Hauser, March 31, 1987 4:08:44 pm PST Demers, May 6, 1987 2:53:16 pm PDT About the Dorado Simulation Environment: 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. General 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. 4. We need to do something to relate PROCESS and SecureProcess! Data Types for Process machinery (wizards only) Sim Locks SIM only. Queues Locks The two pad fields should be combined in RDI. Timeouts Processes There are triggered and rest states. Changing the abortState of process A from a rest state requires holding A's lock (in the ProcessRep structure). Changing the abortState of process A from a triggered state does not require holding the lock, but may only be done by process A itself. Thus a process can check to see if it has been aborted (is in a triggered state) without acquiring a lock. Rest states: Triggered states: THE FOLLOWING NEEDS A LOT OF WORK - ajd The "volatile" state - potentially smashed by interrupt handlers The "non-volatile" state - preserved unless explicitly altered Nachos Nachos are used to save EU & IFU registers associated with local frames. A chain of nachos is used to represent the process call stack. Nachos are fixed size to simplify and speed up allocation. Nachos are pinned to allow us to put a process to sleep without taking page faults. Detaching processes Identity of the currently executing process GetCurrent: PROC RETURNS [SecureProcess] ~ TRUSTED INLINE { }; Priorities of processes GetPriority: SAFE PROC RETURNS [Priority] ~ TRUSTED INLINE { }; Aborting a process Requests that the indicated process be aborted. Checks for the current process being asked to abort by Abort. Raises ABORTED if such a request has been made and aborts are not inhibited (see below). Otherwise CheckForAbort is a null operation. Inhibit (inhibit = TRUE) or uninhibit (inhibit = FALSE) aborts for the current process, and return the previous state of inhibited-ness. If a process has aborts inhibited, ABORTED will not be raised even if the process calls CheckForAbort or waits on a condition that has aborts enabled. Control of Scheduling Process validation Processor data Processors are chained together in a circular queue that is not modified after initialization. Processor data is pinned. There are commands and responses. A processor holding the metaLock may change the orders field of a (possibly different) processor from a response to a command. A processor not holding the metaLock may change its own orders field from a command to a response (indicating that it has committed to following the command). Responses: Commands: Interrupt Handling The interrupt handler will be called for each request of the given kind. On entry to the handler, interrupts will be disabled, the metaLock will be held, and the stack will have been saved. The handler can't touch any code or data that isn't pinned, can't use a lot of time, and can't call procedures so deeply that the IFU or EU stack overflows. In most cases it should just do DelicateNotify[someInterruptConditionVariable] and return. codeK m=HK5K*K"head(Iblock9ei*gMMMLLMaaMM@Kk K KKn  %KK##K0 L K  K  'K  (1.6 in tabStops K1.6 in tabStopsc /K1.6 in tabStops1@K1.6 in tabStopsKK  /K K"&LK  31.6 in tabStopsK1.6 in tabStops/K1.6 in tabStops-K1.6 in tabStopsK1.6 in tabStops1.6 in tabStops6K  BKK  /K1.6 in tabStopsK1.6 in tabStops/K1.6 in tabStops-K1.6 in tabStops K1.6 in tabStopsK1.6 in tabStopsK1.6 in tabStops1.6 in tabStopsK1.6 in tabStopsK1.6 in tabStopsK1.6 in tabStops K1.6 in tabStops1.6 in tabStops  ,K1.6 in tabStops  '1.6 in tabStops  'K1.6 in tabStops)-K1.6 in tabStops K1.6 in tabStops K1.6 in tabStops1.6 in tabStops ( oK1.6 in tabStops1.6 in tabStops%>KK+IKKK  6K  4K  6K %5K  YK  +K!1 K-K&KK ";K   +K   +24 sp tabStops K24 sp tabStops1K24 sp tabStops5CK24 sp tabStops'6K24 sp tabStopsAPK24 sp tabStops 'K24 sp tabStops $K24 sp tabStops/K24 sp tabStops%24 sp tabStops00K1.6 in tabStops)K1.6 in tabStops,K1.6 in tabStops;K24 sp tabStops+K24 sp tabStops K24 sp tabStopsK24 sp tabStops(24 sp tabStops *KK K KKK24 sp tabStops24 sp tabStops  $K24 sp tabStops/=K24 sp tabStops#1K24 sp tabStops +K24 sp tabStops #.K24 sp tabStops *K24 sp tabStops (K24 sp tabStops $1K24 sp tabStops $.K24 sp tabStopsK24 sp tabStops24 sp tabStops (K24 sp tabStops $K24 sp tabStops /K1.6 in tabStops :DK1.6 in tabStops"1K1.6 in tabStopsK1.6 in tabStopsK +KIcode3N  '1.6 in tabStops K1.6 in tabStops 4AK1.6 in tabStops$2K1.6 in tabStops(:K1.6 in tabStops )6K1.6 in tabStops0?K1.6 in tabStops(7K1.6 in tabStopsN #N +GK++ (KK  K  )KKK11K KFxK )K!7K *K!8K  HKKK0K :jKK "KK&K 5KyyKK  /K  /30 sp tabStopsK30 sp tabStops+K30 sp tabStops6OK30 sp tabStopsCVK30 sp tabStops#5K30 sp tabStops !K30 sp tabStopsK30 sp tabStopsK30 sp tabStops,30 sp tabStops ,K30 sp tabStopsKKK$K'K30 sp tabStopsK30 sp tabStops24 sp tabStops +K24 sp tabStops  24 sp tabStops K24 sp tabStops&K24 sp tabStops  024 sp tabStops K24 sp tabStopsATK24 sp tabStops$K24 sp tabStops 'K24 sp tabStopsK24 sp tabStopsK  K  3K  5K*KK 3K3fKKKK`A