-- Cedar Remote Debugging: processes
-- AMProcess.mesa
-- Andrew Birrell February 2, 1983 6:59 pm
DIRECTORY
AMModel USING[ Context ],
PSB USING[ PsbIndex ],
Rope USING[ ROPE ],
RTBasic USING[ TV ],
WorldVM USING[ World ];
AMProcess: DEFINITIONS =
BEGIN
Process: TYPE = RTBasic.TV;
nullProcess: Process = NIL;
PSBIToTV: PROC[world: WorldVM.World, psbi: PSB.PsbIndex] RETURNS[p: Process];
TVToPSBI: PROC[p: Process] RETURNS[world: WorldVM.World, psbi: PSB.PsbIndex];
State: TYPE = {
ready,
waitingCV, waitingML,
frameFault, pageFault, writeProtectFault, unknownFault,
uncaughtSignal, breakpoint, callDebugger,
dead,
unknown };
-- At any instant, each process has a call stack consisting of frames. Frames are ordered by frigidity. A frame's caller is cooler than the frame; making a call instantiates a warmer frame. (I.e. I'm tired of trying to remember which way is "up" on a stack!) Each process may have up to one freezing point on its call stack. Frames cooler than the freezing point are described as frozen, and frames warmer than the freezing are not frozen. If a process returns control to a frozen frame (or control reaches a frozen frame by signal propagation), then the process ceases execution until its freezing point is move (or removed altogether). This interface allows the freezing point of a process to be set, adjusted, and removed. Only the frozen frames of a process may be inspected.
-- Note that a process has at most one freezing point. This is manipulated by the in-world implementation of this interface, and may also be manipulated by a world-swap debugger. In other words, if you invoke a world-swap debugger then the actions performed there may alter the freezing points of processes.
GetProcesses: PROC[context: LIST OF AMModel.Context ← NIL, states: LIST OF State ← NIL]
RETURNS[LIST OF Process];
-- This is the major way to get your hands on a process. The contexts must all be in one world. Enumerates the processes in that world, and includes in the result list each process which, when inspected, is in one of the given states and has on its call stack at least one frame whose global frame is within the given contexts. "context=NIL" is equivalent to the global context of the local world. "states=NIL" is equivalent to a list containing every state. If any of the interesting frames is not frozen, this will move the freezing point of the process so that all such frames are frozen; but it will not thaw any frames. In other words, this will return all processes which are associated with a given set of contexts and which are in interesting states, and ensures that the processes will no longer execute inside the contexts. Examples of interesting special cases: "GetProcesses[world]" returns all processes in a world and freezes all their frames; "GetProcesses[world, LIST[pageFault]]" returns all processes in a world that are presently waiting for resolution of a page fault, and freezes all their frames; "GetProcesses[LIST[someContext]]" returns all processes involved with the context and prevents them executing within the context.
-- Any of the following may raise RTTypes.Error[typeFault, ....] if given an invalid process.
Name: PROC[p: Process] RETURNS[Rope.ROPE];
-- Returns a human-sensible world-relative name for the process, currently of the form "PSB 237B" --
Freeze: PROC[processes: LIST OF Process, context: LIST OF AMModel.Context ← NIL];
-- For each process, determines the warmest frame on its call stack that is within the given contexts. If this frame is not frozen, this will move the freezing point of the process so that all such frames are frozen; but it will not thaw any frames. "context=NIL" is equivalent to the global context of the appropriate world.
Adjust: PROC[processes: LIST OF Process, context: LIST OF AMModel.Context ← NIL];
-- For each process, determines the warmest frame on its call stack that is within the given contexts. Adjusts the freezing point of the process so that this frame and any cooler ones are frozen, but any warmer ones are no longer frozen. "context=NIL" is equivalent to the global context of the appropriate world.
Thaw: PROC[processes: LIST OF Process];
-- For each process, remove any freezing point, so that none of its frames is frozen.
GetState: PROC[p: Process]
RETURNS[state: State,
faultData: LONG CARDINAL,
priority: [0..7],
stack: RTBasic.TV,
topFrame: BOOL];
-- Returns the instantaneous state of the process. If the state is in [frameFault..writeProtectFault] then "faultData" is the corresponding data (as defined in the PrincOps). "priority" is the priority! If the process has a freezing point, then "stack" is the warmest frozen frame, otherwise "stack" is NIL. "topFrame" is true iff "stack" is the current frame of the process (which implies that the process has ceased execution).
CallDebugger: PROC[p: Process, msg: Rope.ROPE];
-- Causes a "CallDebugger" event to be reported for the process at its warmest froxen frame.
-- If there is no froxen frame, first freezes the process at its warmest frame.
Abort: PROC[p: Process];
-- When next the process waits on a CV, or immediately if the process is currently
-- waiting on a CV or waiting on a ML at an ENTRY procedure, cause ABORTED to be raised.
-- If the process's current frame is frozen, this will not take effect until that frame is thawed.
ReturnFrom: PROC[p: Process, frame: RTBasic.TV, result: RTBasic.TV];
-- Immediately raises ABORTED in the victim process. If "frame" is not NIL, catches the
-- ABORTED (indeed, ANY) when it propagates past "frame", and emulates return from "frame"
-- with "result". This effectively causes an UNWIND from the top of stack through
-- "frame", unless someone catches the ABORTED earlier.
-- If the process's current frame is frozen, this will not take effect until that frame is thawed.
-- With the present (rubicon) catch phrase mechanism, the most recent frame of the
-- process at the time ABORTED is raised will not see the UNWIND.
Retry: PROC[p: Process, frame: RTBasic.TV, args: RTBasic.TV];
-- As for "ReturnFrom", but after returning from "frame", the procedure corresponding
-- to "frame" is called with the new "args".
-- If the process's current frame is frozen, this will not take effect until that frame is thawed.
LocalOnly: ERROR;
-- "Abort", "ReturnFrom", and "Retry" are implemented only in the local world. Otherwise
-- this error is raised.
END.