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; }; }. 4DruidImpl.mesa Copyright Σ 1990, 1992 by Xerox Corporation. All rights reserved. Peter B. Kessler, August 7, 1990 11:00 am PDT Sets a counting breakpoint at the given address. If monitored, then changes to the megalith are monitored, else not. Clears the given counting break. Checks whether the given megalith is active. Reads the counter in the given counting break. Zeroes the counter in the given counting break. PROCEDURE [breakData: BreakData] RETURNS [] Hans says he'll include this procedure in the next storage allocator package. For now ... ΚK–(cedarcode) style•NewlineDelimiter ˜codešœ™Kšœ Οeœ7™BK™-—˜šΟk ˜ Kšœ˜K˜ K˜Kšœ ˜ Kšœ˜Kšœ˜K˜——unitšΠln œžœž˜Kšžœ žœ˜'Kšžœ3˜:Kšžœ˜Kšœ˜K˜šœ žœžœžœ"˜=Kšœ žœžœ;˜SK˜—š Οnœžœž œ7žœžœžœ˜zK™0KšœC™Cšœžœ˜.Kšœ>˜>—š  œž œžœž œžœžœžœžœ!˜iK˜9Kšœ&žœ˜6K˜Kšžœ ˜K˜—˜0KšœI˜I—˜4Kšœ˜—˜8˜"K˜9——˜*Kšœ˜KšœΟc˜5Kšœ!˜!Kšœ žœ ˜—Kšžœ ˜K˜—K˜š œžœž œžœ˜AK™ š œžœž œžœ˜IKšžœžœžœ˜Kšœ%˜%Kšžœ˜K˜—š œž œžœ˜Ešžœžœ˜K˜2K˜&K˜—Kšžœ˜K˜—šžœ žœžœ˜šžœ˜Kšžœžœžœ˜?—K˜—Kšžœ˜K˜K™—š  œžœž œžœžœ˜KK™,Kšžœ žœžœ(˜BK˜K™—š  œžœž œžœžœ˜DK™.Kšœžœ˜K˜šžœžœ˜K˜K˜—Kšžœ˜K˜K™—š  œžœž œžœžœ˜DK™/Kšœžœ˜š   œžœž œžœžœ˜LKšžœžœžœ˜Kšœžœ'˜1K˜Kšžœ˜K˜—š œž œžœžœ˜HKšœžœ˜K˜šžœžœ˜K˜K˜K˜—Kšžœ˜K˜—K˜šœžœ˜Kšžœžœ&˜=—Kšžœ˜K˜K™—š  œžœ˜0Kšž œžœ™+š  œž œ#žœžœžœ˜KKšœžœžœžœ˜š   œžœž œžœžœžœ˜AK™ZKšžœžœ˜K˜K˜—šžœžœžœ˜&Kšœ žœ ˜K˜—Kšžœ ˜K˜—Kšœ žœžœ"˜2K˜šžœ žœž˜˜š œžœž œ˜BKšžœžœžœ˜K˜)Kšžœ˜K˜—š œž œ˜>K˜$Kšžœ˜K˜—šœžœ˜Kšžœžœ+˜G—K˜—Kšžœžœ˜—Kšžœ˜K˜K˜—L˜——…—4³