DIRECTORY Allocator USING[NHeaderP, RefCount], AllocatorOps USING[REFToNHP], UnsafeStorage USING[GetSystemUZone], ZCT USING[IncrForUnderflow, DecrForOverflow]; RCOvImpl: MONITOR -- protects rcOverflowChain IMPORTS AllocatorOps, UnsafeStorage, ZCT EXPORTS ZCT = BEGIN OPEN Allocator, AllocatorOps, ZCT; rcDelta: RefCount = 16; RCOverflowChain: TYPE = LONG POINTER TO RCOverflowChainRec; RCOverflowChainRec: TYPE = RECORD[ nhp: NHeaderP, count: NAT, -- count of rcDelta deposits in the bank for this REF rest: RCOverflowChain ]; uz: UNCOUNTED ZONE = UnsafeStorage.GetSystemUZone[]; rcOverflowChain: RCOverflowChain _ NIL; -- Statistics Count: TYPE = INT; takingStatistics: BOOL = TRUE; Bump: PROC[p: POINTER TO Count, delta: Count _ 1] = INLINE {IF takingStatistics THEN p^ _ p^+delta}; StatsRec: TYPE = RECORD [ nHandleRCUnderflow: Count _ 0, nHandleRCOverflow: Count _ 0, nOldDeposit: Count _ 0, nNewDeposit: Count _ 0, nInnerWithdrawal: Count _ 0, nLastWithdrawal: Count _ 0 ]; stats: StatsRec _ []; -- the one and only EnterRCOvAndCallBack: PUBLIC ENTRY PROC[proc: PROC] = {ENABLE UNWIND => NULL; proc[]; }; RCOvReset: PUBLIC --INTERNAL-- PROC = { rl: RCOverflowChain _ rcOverflowChain; UNTIL rl = NIL DO next: RCOverflowChain _ rl.rest; uz.FREE[@rl]; rl _ next; ENDLOOP; rcOverflowChain _ NIL; }; InnerHandleRCUnderflow: PUBLIC --INTERNAL-- PROC[ref: REF] = { nhp: NHeaderP _ REFToNHP[ref]; Bump[@stats.nHandleRCUnderflow]; IF nhp.refCount # 0 OR NOT nhp.rcOverflowed THEN ERROR; nhp.refCount _ nhp.refCount + rcDelta; IF Withdraw[nhp].accountClosed THEN nhp.rcOverflowed _ FALSE; }; HandleRCUnderflow: PUBLIC ENTRY PROC[ref: REF] = {ENABLE UNWIND => NULL; nhp: NHeaderP _ REFToNHP[ref]; Bump[@stats.nHandleRCUnderflow]; IF nhp.rcOverflowed AND IncrForUnderflow[rcDelta, nhp].success AND Withdraw[nhp].accountClosed THEN nhp.rcOverflowed _ FALSE; }; InnerHandleRCOverflow: PUBLIC --INTERNAL-- PROC[ref: REF] = { nhp: NHeaderP _ REFToNHP[ref]; Bump[@stats.nHandleRCOverflow]; IF nhp.refCount # LAST[RefCount] THEN ERROR; nhp.refCount _ nhp.refCount - rcDelta; nhp.rcOverflowed _ TRUE; -- mark nhp as having an rc deposit Deposit[nhp]; }; HandleRCOverflow: PUBLIC ENTRY PROC[ref: REF] = {ENABLE UNWIND => NULL; nhp: NHeaderP _ REFToNHP[ref]; Bump[@stats.nHandleRCOverflow]; IF NOT DecrForOverflow[rcDelta, nhp].success THEN RETURN; nhp.rcOverflowed _ TRUE; -- mark nhp as having an rc deposit Deposit[nhp]; }; Deposit: --INTERNAL-- PROC[nhp: Allocator.NHeaderP] = { FOR rl: RCOverflowChain _ rcOverflowChain, rl.rest UNTIL rl = NIL DO IF nhp = rl.nhp THEN {rl.count _ rl.count + 1; Bump[@stats.nOldDeposit]; RETURN} ENDLOOP; Bump[@stats.nNewDeposit]; rcOverflowChain _ uz.NEW[RCOverflowChainRec _ [nhp: nhp, count: 1, rest: rcOverflowChain]]; }; Withdraw: --INTERNAL-- PROC[nhp: Allocator.NHeaderP] RETURNS[accountClosed: BOOL] = { rl: RCOverflowChain; prev: RCOverflowChain _ NIL; FOR rl _ rcOverflowChain, rl.rest UNTIL rl = NIL DO IF nhp = rl.nhp THEN { rl.count _ rl.count - 1; IF rl.count = 0 THEN { -- close the account IF prev = NIL THEN rcOverflowChain _ rl.rest ELSE prev.rest _ rl.rest; uz.FREE[@rl]; Bump[@stats.nLastWithdrawal]; RETURN[TRUE]; } ELSE {Bump[@stats.nInnerWithdrawal]; RETURN[FALSE]}; } ELSE prev _ rl; ENDLOOP; ERROR; }; END. ¸RCOvImpl.mesa Last Modified On December 6, 1983 11:14 am By Paul Rovner usage: Bump[@stats.nHandleRCUnderflow]; Called from the TAndS collector Called from the TAndS collector Called from the TAndS ... the decrement was NOT done HandleRCUnderflow may pageFault Called from AssignRef and from ReclaimedRef ... the decrement was NOT done HandleRCUnderflow may pageFault This and the above proc are the only ones that set nhp.rcOverflowed _ FALSE Called only from the TAndS ... NEITHER the increment nor the assignment was done Called only from AssignRef ... NEITHER the increment nor the assignment was done This and InnerHandleRCOverflow are the only procs that set nhp.rcOverflowed _ TRUE Ê\˜J™ J™9J˜šÏk ˜ Jšœ œ˜$Jšœ œ ˜Jšœœ˜$Jšœœ$˜-—J˜Jšœ œÏc˜.Jšœ˜(Jšœ˜ J˜Jšœ œ˜*J˜Jšœ˜Jš œœœœœ˜;šœœœ˜"Jšœ˜Jšœœž6˜CJ˜J˜—J˜Jšœ œœ#˜5Jšœ#œ˜'J˜šž ˜ Jšœœœ˜Jšœœœ˜šÏnœœœœ˜3Jšœ'™'Jšœœœ˜0—J˜Jšœ œ˜Jšœ ˜ Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜J˜Jšœž˜*—˜Jšœ™—šÐbnœœœœœœœœ˜MJšœ˜Jšœ˜J˜Jšœ™—šŸ œœž œœ˜'Jšœ&˜&šœœ˜Jšœ ˜ Jšœœ˜ Jšœ ˜ Jšœ˜—Jšœœ˜Jšœ˜J˜Jšœ4™4Jšœ™—š Ÿœœž œœœ˜>Jšœ˜Jšœ ˜ Jš œœœœœ˜7Jšœ&˜&Jšœœœ˜=Jšœ˜J˜JšœJ™JJšœ™JšœF™K—šŸœœœœœœœœ˜HJšœ˜Jšœ ˜ šœ˜Jšœ'˜*Jšœ˜Jšœœ˜—Jšœ˜J˜Jšœœ*™P—š Ÿœœž œœœ˜=Jšœ˜Jšœ˜Jšœœ œœ˜,Jšœ&˜&Jšœœž#˜=Jšœ ˜ Jšœ˜J˜JšœP™PJšœR™R—šŸœ œœœœœœ˜GJšœ˜Jšœ˜Jšœœ'œœ˜9Jšœœž#˜=Jšœ ˜ Jšœ˜J˜šŸœž œœ˜7šœ0œ˜AJšœœ4œœ˜\—Jšœ˜šœ˜JšœœC˜K—Jšœ˜J˜—š Ÿœž œœœœ˜UJšœ˜Jšœœ˜šœœœ˜3šœœ˜Jšœ˜šœœž˜,šœ˜ Jšœ˜Jšœ˜—Jšœœ˜ Jšœ˜Jšœœ˜ J˜—Jšœœœ˜4J˜—Jšœ ˜Jšœ˜—Jšœ˜Jšœ˜J˜——Jšœ˜J˜J˜—…— Úî