DIRECTORY AMTypes USING [nullType], IO USING [STREAM], PrincOps USING [BytePC, GlobalFrameHandle, PsbHandle]; SpyLog: DEFINITIONS = BEGIN active: READONLY BOOL; -- true iff the spy is open for writing. OpenForRead: PROC; OpenForWrite: PROC [spyOnSpyLog: BOOL _ FALSE]; Close: PROC; Print: PROC [stream: IO.STREAM _ NIL]; Entry: TYPE = MACHINE DEPENDENT RECORD [ SELECT type:{endOfLog, nullEntry, trace, data} FROM endOfLog => [fill: [0..16000)_0], -- marks the end of valid data nullEntry => [size: [0..16000)_0], -- indicates data to be skipped (used internally). trace => [ -- 6 words fill: [0..16000)_0, gfh: PrincOps.GlobalFrameHandle, pc: PrincOps.BytePC, process: PrincOps.PsbHandle, timestamp: CARD], data => [ -- 4 words + size size: [0..16000), rttype: CARDINAL, timestamp: CARD, data: SEQUENCE COMPUTED CARDINAL OF WORD], ENDCASE]; InvisibleProcesses: PROC RETURNS [writeProcess:PROCESS, extendProcess: PROCESS]; NextEntry: PROC RETURNS [LONG POINTER TO Entry]; WriteData: PROC [data: LONG POINTER, size: [0..8000], type: CARDINAL _ AMTypes.nullType]; WriteTrace: PROC [gfh: PrincOps.GlobalFrameHandle _ NIL, pc: PrincOps.BytePC _ [0]]; Here: PROC = INLINE {IF active THEN WriteTrace[]}; Error: ERROR; END. Bob Hagmann October 24, 1986 11:25:34 am PDT ¬SpyLog.mesa Copyright Σ 1985, 1987 by Xerox Corporation. All rights reserved. Maxwell, September 16, 1983 11:07 am Russ Atkinson (RRA) February 16, 1987 11:18:09 am PST Bob Hagmann October 24, 1986 11:25:23 am PDT The Spy log is a fast means of logging information. It is guaranteed not to cause any page faults or allocations for the client process. It is implemented with two pinned buffers, one of which is being written out to the disk by a separate process while the other is being filled with data. Normally there is only one log, which can be written or read, but not both. Calling OpenForRead with spyOnSpyLog = TRUE will create a second log that can be written to while the first log is being read. After the first log is read, calling OpenForRead again will open the second log for reading. Control Opens the spy log for reading. Opens the spy log for writing. If spyOnSpyLog is TRUE, then use the secondary log. Unpins the buffers and the module. Does not destroy any information. There is no need to close the log if you are just going to re-open it in a different mode. Reading and Writing Returns the processes that are the current writer and extender, or NIL if no process exists. Do not call WriteData or WriteTrace from either of these processes. Moves the index to the next entry. The last entry will contain [endOfLog[]]. Raises Error if the spy log is not open for reading. Examples: WriteData[@foo, SIZE[Foo], CODE[Foo]]; WriteData[@data, size]. The system will store the type and use it to print the data. This doesn't slow down the spying; the costs are incurred when the log is printed. The type cannot be ref-containing. Raises Error if the spy log is not open for writing. Records the gfh and pc. This will be printed as a procedure and pc. Defaults to the gfh and pc of the calling procedure. Raises Error if the spy log is not open for writing. Very cheap if the log isn't activated. added WriteProcess ΚΊ˜codešœ ™ KšœB™BK™$K™5K™,—™šΟk ˜ Kšœœ ˜Kšœœœ˜Kšœ œ(˜6K˜——šΟnœ œ˜K™Kšœšœ³™Ρ—head2™KšœœœΟc(˜?K˜šž œœ˜Kšœ™K™—šž œœœœ˜/Kšœ2œ™UK™—šžœœ˜Kšœ‘™‘K™—Kš žœœ œœœ˜(—šœ™š œœœ œœ˜(šœ)˜3Kšœ"Ÿ˜@Kšœ#Ÿ2˜Ušœ Ÿ ˜Kšœ˜Kšœ ˜ K˜Kšœ˜Kšœ œ˜—šœ Ÿ˜Kšœ˜Kšœœ˜Kšœ œ˜Kš œœœœœœ˜*—Kšœ˜ ——K˜š žœœœœœ˜QKšœ‘™‘K˜—š ž œœœœœœ ˜1Kšœƒ™ƒK˜—š ž œœœœœ˜YKšœœœŠ™³K˜—šž œœ$œ˜TKšœ―™―K˜—š žœœœœœ˜3K™&—K˜Kšœœ˜ —K˜Kšœ˜K˜˜,KšΟrœ ™——…—h