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]; 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 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 [SecureProcess]; SetPriority: SAFE PROC [p: Priority]; Abort: PROC [SecureProcess]; 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 [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 { 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. 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, April 30, 1987 6:31:55 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 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: SAFE 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. Otherwise CheckForAbort is a null operation. 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. Interrupt Handling The interrupt handler will be called for each request of the given kind. On entry to the handler, interrupts will be disabled and the metaLock will be held. The handler can't touch any code or data that isn't pinned, and can't use a lot of time. 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!1K1.6 in tabStopsK AK2V 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 KFOK *K!8K )K!7 KK 5K :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 +K24 sp tabStops&K24 sp tabStopsATK24 sp tabStops2AK24 sp tabStops  /K24 sp tabStopsK24 sp tabStopsK  K  3K  5K*KK 3K3kKKKK\=