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; 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 Copyright c 1985 by Xerox Corporation. All rights reserved. Paul Rovner, December 6, 1983 11:14 am Russ Atkinson (RRA) February 1, 1985 1:27:05 pm PST Statistics 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 Κr˜code™ Kšœ Οmœ1™Kšœ˜Kšœ ˜ Kš žœžœžœžœžœ˜7Kšœ&˜&Kšžœžœžœ˜=Kšœ˜K˜KšœJ™JKšœ™KšœFž™K—š œžœžœžœžœžœžœžœ˜HKšœ˜Kšœ ˜ šžœ˜Kšžœ'˜*Kšžœ˜Kšžœžœ˜—Kšœ˜K˜Kšœžœ*™P—š  œžœŸ œžœžœ˜=Kšœ˜Kšœ˜Kšžœžœ žœžœ˜,Kšœ&˜&KšœžœŸ#˜=Kšœ ˜ Kšœ˜K˜KšœP™PKšœR™R—š œž œžœžœžœžœžœ˜GKšœ˜Kšœ˜Kšžœžœ'žœžœ˜9KšœžœŸ#˜=Kšœ ˜ Kšœ˜K˜š œŸ œžœ˜7šžœ0žœž˜AKšžœžœ4žœžœ˜\—Kšœ˜šœ˜KšœžœC˜K—Kšœ˜K˜—š  œŸ œžœžœžœ˜UKšœ˜Kšœžœ˜šžœžœžœž˜3šžœžœ˜Kšœ˜šžœžœŸ˜,šžœž˜ Kšžœ˜Kšžœ˜—Kšœžœž˜ Kšœ˜Kšžœžœ˜ K˜—Kšžœžœžœ˜4K˜—Kšžœ ˜Kšžœ˜—Kšžœ˜Kšœ˜K˜——Kšžœ˜K˜K˜—…— ΒT