AMEventsBackdoorExtra.mesa: backdoor interactions with client
Copyright © 1985 by Xerox Corporation. All rights reserved.
Bob Hagmann, November 26, 1985 1:43:22 pm PST
DIRECTORY
AMEvents USING[ EventProc ],
AMTypes USING [ TV ],
DebuggerFormat USING [ DebugParameter, ExternalStateVector, SwapInfo ],
PrincOps USING[ StateVector ],
WorldVM USING[ Address, World ];
AMEventsBackdoorExtra: DEFINITIONS = BEGIN
World: TYPE = WorldVM.World;
Address: TYPE = WorldVM.Address;
DebugParameter: TYPE = DebuggerFormat.DebugParameter;
EventProc: TYPE = AMEvents.EventProc;
StateVector: TYPE = PrincOps.StateVector;
ExternalStateVector: TYPE = DebuggerFormat.ExternalStateVector;
TV: TYPE = AMTypes.TV;
Management of event watchers ("Actor") for each world
Actor: TYPE = REF ActorObject;
ActorObject: TYPE = RECORD[
common fields
next: Actor,
world: World,
data: REF, -- data to be passed back to the event proc
proc: EventProc, -- event notification handler
users: INT ← 1, -- reference count on GetEvents/StopEvents
the remainder is only for world-swap and teledebug clients
running: BOOLTRUE, -- client is running
listener: PROCESSNIL, -- if not NIL, the process looking at the client
bootCount: INT ← 0, -- incremented when a client session ends
level: CARDINAL ← 0, -- nesting level of client procedure calls
the remainder is data for interfacing with client
swapInfo: DebuggerFormat.SwapInfo ← NULL,
esvAddr: Address ← 0,
esv: ExternalStateVector ← NULL,
paramAddr: Address ← 0,
param: DebugParameter ← NULL,
stateAddr: Address ← 0,
state: StateVector ← NULL ];
Locking for fields in an ActorObject:
Immutable: a.world, a.data, a.proc.
Inside monitor: a.next, a.users, a.running, a.listener, a.bootCount
By claiming "running": a.swapInfo, a.esvAddr, a.esv, a.paramAddr, a.param, a.stateAddr, a.state
"a.level" is altered with the monitor and a.running claimed, so it may be read either inside the monitor or by claiming a.running.
There are three sources of synchronisation problems:
* ensuring that only one process transfers control to the client at a time
* the client booting
* someone calling "StopEvents"
The a.running field provides mutual exclusion on transferring to the client.
The a.bootCount field indicates when the client has booted. This is notified to the public through the BootedNotifiers.
Having a.users=0 indicates a desire to disconnect from the client. This is notified to the BootedNotifiers and by aborting a.listener.
Note that we never access the client with our monitor locked: local events require access to our monitor, but access to a remote client involves unbounded delays.
Some low level errors
KillThisTurkey: ERROR;
NotImplemented: ERROR;
BreakNotFound: ERROR;
Some control variables
SupressUncaughtAborted: BOOL;
This is TRUE to kill off processes that do not have a base frame that catches ABORTED and flush out the process. This makes it easier to kill off processes. You can set this FALSE to find processes that are being aborted when you don't think that they are.
CrashOnRecursiveAppearance: BOOL;
RRA: We can set this to TRUE to carsh when a signal appears to be recursive. Experience has shown that signals appear to be recursive more often than they are recursive, however.
Informing: BOOL;
Whether to raise the informational signals. You have to remember that ANY handles informational signals, so you probably want to use RuntimeError.UNCAUGHT to handle errors that others will not handle.
Wsls: BOOL;
If TRUE, will world-swap uncaught local signals, instead of sending them to the registered handler. This is useful before the handler is established, or when the handler is buggy.
Actors: Actor ; -- the list of event watchers
LocalActor: Actor ;
PSBIToTV: PROC [psbi: CARDINAL, world: World] RETURNS [p: TV];
END.
Bob Hagmann November 26, 1985 1:42:40 pm PST
created interface