Queues
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;
Processes
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 {
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:
none (0), -- process not requested to abort
inhibited (1), -- process abort not allowed
Triggered states:
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
};
THE FOLLOWING NEEDS A LOT OF WORK - ajd
EUstateIndex:
TYPE ~
MACHINE
DEPENDENT {
The "volatile" state - potentially smashed by interrupt handlers
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
The "non-volatile" state - preserved unless explicitly altered
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;
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.
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
Aborting a process
Abort:
PROC [SecureProcess];
Requests that the indicated process be aborted.
CheckForAbort:
PROC;
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.
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];
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.