<> <> <> 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] ~ { <> <> 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 [] ~ { <> 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] ~ { <> RETURN [megalith # NIL AND megalith.break # Breakpoint.nullBreak]; }; <<>> Read: PUBLIC PROCEDURE [megalith: Druid.Megalith] RETURNS [CARD] ~ { <> read: CARD ¬ 0; IF megalith.IsActive[] THEN { read ¬ megalith.count; }; RETURN [read]; }; <<>> Zero: PUBLIC PROCEDURE [megalith: Druid.Megalith] RETURNS [CARD] ~ { <> 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 ~ { <> ToRefAny: PROCEDURE [breakData: Breakpoint.BreakData] RETURNS [REF ANY] ~ { refAny: REF ANY ¬ NIL; IsARefAny: PRIVATE PROCEDURE [data: CARD32] RETURNS [BOOLEAN] ~ { <> 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; }; }.