SpyOps.mesa
edited by: Maxwell April 28, 1983 3:11 pm
DIRECTORY
FastBreak USING [FastBreakProc],
IO USING [STREAM],
PrincOps USING [BytePC, FrameHandle, GFTIndex, GlobalFrameHandle],
PrincOpsRuntime USING [GetFrame, GFT],
Process USING [GetCurrent, Priority],
PSB USING [PsbIndex, PsbNull],
Rope USING [ROPE],
SpyClient USING [DataType],
System USING [Pulses];
SpyOps: DEFINITIONS IMPORTS PrincOpsRuntime, Process = BEGIN
ROPE: TYPE = Rope.ROPE;
**********************************************************
SpyKernel procedures and data structures
**********************************************************
InitializeSpy: PROCEDURE[
dataType: DataType ← CPU,
process: PSB.PsbIndex ← PSB.PsbNull]
RETURNS[errorMsg: ROPE];
StartCounting: FastBreak.FastBreakProc;
StopCounting: FastBreak.FastBreakProc;
Record: PROCEDURE[
psbi: PSB.PsbIndex ← LOOPHOLE[Process.GetCurrent[]],
frame: PrincOps.FrameHandle ← NIL,
type: StackType ← 0,
count: CARDINAL ← 1];
UserBreak: FastBreak.FastBreakProc; -- calls Record
current parameters
spyState: READONLY SpyState;
watching: READONLY DataType;
justMe: READONLY PSB.PsbIndex;
statistics
runningTime: System.Pulses;
active, starts, stops: INTEGER;
pageFaults: LONG CARDINAL;
wordsAllocated: LONG CARDINAL;
wordsReclaimed: LONG CARDINAL;
wakeups, notScheduled, skips: Count;
levelData: LevelData;
data types
DataType: TYPE = SpyClient.DataType;
SpyState: TYPE = {off, on, disabled};
Stack: TYPE = MACHINE DEPENDENT RECORD [
process: PSB.PsbIndex,
level: Process.Priority,
type: StackType,
count: CARDINAL,
frame: ARRAY [0..stackLength) OF Frame];
stackLength: CARDINAL = 75;
stackHeader: CARDINAL = Stack.SIZE - stackLength*Frame.SIZE;
StackType: TYPE = CARDINAL [0..7);
Frame: TYPE = MACHINE DEPENDENT RECORD[
unused: CARDINAL [0..64),
gfi: PrincOps.GFTIndex, pc: PrincOps.BytePC];
Count: TYPE = INT;
LevelData: TYPE = ARRAY Process.Priority OF Count;
**********************************************************
SpyBreaks and SpyLogReader
**********************************************************
-- SpyBreaks procedures --
PrintBreaks: PROCEDURE[typescript: IO.STREAM];
SetSensitiveBreak: PROCEDURE[type: DataType] RETURNS[msg: ROPE];
-- SpyLogReader procedures --
ZeroLog: PROCEDURE;
DestroyLog: PROCEDURE;
ReadLog: PROCEDURE[typescript: IO.STREAM, datatype: DataType];
processes: LIST OF ProcessRef;
modules: LIST OF Procedure;
ProcessRef: TYPE = REF ProcessRec;
ProcessRec: TYPE = RECORD[
psb: PSB.PsbIndex ← 0,
level: PACKED ARRAY [0..4] OF Process.Priority ← ALL[0],
calls: Count ← 0,
sons: LIST OF Call ← NIL];
Procedure: TYPE = REF ProcRec;
ProcRec: TYPE = RECORD [
unused: BOOLEANFALSE,
marked: BOOLEANFALSE, -- bit for procedures that walk the stack
named: BOOLEANFALSE, -- have we appended the name of the procedure?
symbols: BOOLEANTRUE, -- are the symbols available?
gfi: PrincOps.GFTIndex ← 0, -- gfi for this procedure
name: ROPENIL, -- the name of the procedure
entryPC: CARDINAL ← 0,
exitPC: CARDINALLAST[CARDINAL],
refs: CARDINAL ← 0, -- number of procedures that call this one
count: Count ← 0, -- counts in this procedure
calls: Count ← 0, -- counts in procedures called by this one
container: Procedure ← NIL, -- the procedure that contains all calls to this one
parents: LIST OF Procedure ← NIL, -- procedures that call this one
sons: LIST OF Call ← NIL]; -- procedures called from here
Call: TYPE = RECORD[
pc: CARDINAL ← 0,
calls: Count ← 0,
proc: Procedure ← NIL];
GFHFromGFI: PROCEDURE[gfi: PrincOps.GFTIndex]
RETURNS[PrincOps.GlobalFrameHandle] = INLINE
{RETURN[PrincOpsRuntime.GetFrame[PrincOpsRuntime.GFT[gfi]]]};
END . .