DruidImpl.mesa
Copyright Ó 1990, 1992 by Xerox Corporation. All rights reserved.
Peter B. Kessler, August 7, 1990 11:00 am PDT
DIRECTORY
Druid,
DruidPrivate,
TargetArchitecture,
Breakpoint,
BreakWorldArchitecture,
UXProcs;
DruidImpl: CEDAR MONITOR
LOCKS megalith USING megalith: Megalith
IMPORTS Druid, Breakpoint, BreakWorldArchitecture, UXProcs
EXPORTS Druid
~ {
Megalith: PUBLIC TYPE ~ REF MegalithRep ¬ Druid.nullMegalith;
MegalithRep: PUBLIC TYPE ~ DruidPrivate.MegalithRep ¬ DruidPrivate.nullMegalithRep;
Set: PUBLIC PROCEDURE [
address: BreakWorldArchitecture.Address,
monitored: BOOLEAN ¬ FALSE]
RETURNS [Druid.Megalith] ~ {
Sets a counting breakpoint at the given address.
If monitored, then changes to the megalith are monitored, else not.
megalith: Druid.Megalith ¬ NEW[MegalithRep ¬ [
count: 0, break: Breakpoint.nullBreak, monitored: monitored]];
ProcToAddress: PROCEDURE [proc: SAFE PROCEDURE ANY RETURNS ANY]
RETURNS [TargetArchitecture.Address] ~ {
cProc: UXProcs.CProc ~ UXProcs.FromCedarProc[proc: proc];
address: TargetArchitecture.Address ~ LOOPHOLE[cProc];
RETURN [address];
};
breakWorld: BreakWorldArchitecture.BreakWorld ~
BreakWorldArchitecture.BreakWorldFromBreakWorldAddress[address: address];
breakProcTargetAddress: TargetArchitecture.Address ~
ProcToAddress[proc: BreakProc];
breakProcWorldAddress: BreakWorldArchitecture.Address ~
BreakWorldArchitecture.NewAddress[
breakWorld: breakWorld, address: breakProcTargetAddress];
megalith.break ¬ Breakpoint.SetBreakpoint[
address: address,
clientData: megalith, -- anything useful to put here?
breakProc: breakProcWorldAddress,
breakData: LOOPHOLE[megalith]];
RETURN [megalith];
};
Clear: PUBLIC PROCEDURE [megalith: Druid.Megalith] RETURNS [] ~ {
Clears the given counting break.
MonitoredClear: ENTRY PROCEDURE [megalith: Druid.Megalith] RETURNS [] ~ {
ENABLE UNWIND => NULL;
UnmonitoredClear[megalith: megalith];
RETURN;
};
UnmonitoredClear: PROCEDURE [megalith: Druid.Megalith] RETURNS [] ~ {
IF megalith.IsActive[] THEN {
Breakpoint.ClearBreakpoint[break: megalith.break];
megalith.break ¬ Breakpoint.nullBreak;
};
RETURN;
};
IF megalith # NIL THEN {
(IF megalith.monitored
THEN MonitoredClear ELSE UnmonitoredClear)[megalith: megalith];
};
RETURN;
};
IsActive: PUBLIC PROCEDURE [megalith: Druid.Megalith] RETURNS [BOOLEAN] ~ {
Checks whether the given megalith is active.
RETURN [megalith # NIL AND megalith.break # Breakpoint.nullBreak];
};
Read: PUBLIC PROCEDURE [megalith: Druid.Megalith] RETURNS [CARD] ~ {
Reads the counter in the given counting break.
read: CARD ¬ 0;
IF megalith.IsActive[] THEN {
read ¬ megalith.count;
};
RETURN [read];
};
Zero: PUBLIC PROCEDURE [megalith: Druid.Megalith] RETURNS [CARD] ~ {
Zeroes the counter in the given counting break.
read: CARD ¬ 0;
MonitoredZero: ENTRY PROCEDURE [megalith: Druid.Megalith] RETURNS [CARD] ~ {
ENABLE UNWIND => NULL;
read: CARD ~ UnmonitoredZero[megalith: megalith];
RETURN [read];
};
UnmonitoredZero: PROCEDURE [megalith: Druid.Megalith] RETURNS [CARD] ~ {
read: CARD ¬ 0;
IF megalith.IsActive[] THEN {
read ¬ megalith.count;
megalith.count ¬ 0;
};
RETURN [read];
};
read ¬ (IF megalith.monitored
THEN MonitoredZero ELSE UnmonitoredZero)[megalith: megalith];
RETURN [read];
};
BreakProc: PRIVATE Breakpoint.BreakProcedure ~ {
PROCEDURE [breakData: BreakData] RETURNS []
ToRefAny: PROCEDURE [breakData: Breakpoint.BreakData] RETURNS [REF ANY] ~ {
refAny: REF ANY ¬ NIL;
IsARefAny: PRIVATE PROCEDURE [data: CARD32] RETURNS [BOOLEAN] ~ {
Hans says he'll include this procedure in the next storage allocator package. For now ...
RETURN [TRUE];
};
IF IsARefAny[breakData] THEN TRUSTED {
refAny ¬ LOOPHOLE[breakData];
};
RETURN [refAny];
};
refData: REF ANY ~ ToRefAny[breakData: breakData];
WITH refData SELECT FROM
megalith: Megalith => {
MonitoredIncrement: ENTRY PROCEDURE [megalith: Druid.Megalith] ~ {
ENABLE UNWIND => NULL;
UnmonitoredIncrement[megalith: megalith];
RETURN;
};
UnmonitoredIncrement: PROCEDURE [megalith: Druid.Megalith] ~ {
megalith.count ¬ megalith.count + 1;
RETURN;
};
(IF megalith.monitored
THEN MonitoredIncrement ELSE UnmonitoredIncrement)[megalith: megalith];
};
ENDCASE => NULL;
RETURN;
};
}.