DIRECTORY Allocator USING [bsiEscape, ExtendedHeader, HeaderP, NHeaderP, pagesPerQuantum, QuantumIndex, wordsPerQuantum, LastAddress, NormalHeader], AllocatorOps USING [EnterAndCallBack, quantumMap, BlockSize], Process USING [Pause], SafeStorage USING [Type], SweepCollectableStorage USING [InfoProc], VM USING [Interval, SwapIn], ZCT USING [EnterAndCallBack, EnterRCOvAndCallBack]; SweepCollectableStorageImpl: PROGRAM IMPORTS AllocatorOps, Process, VM, ZCT EXPORTS SweepCollectableStorage = BEGIN OPEN Allocator, AllocatorOps, SafeStorage; currentQuantumStart: Allocator.QuantumIndex; LPToQuantumIndex: PROC[lp: LONG POINTER] RETURNS[QuantumIndex] = { RETURN[LOOPHOLE[lp, LONG CARDINAL]/wordsPerQuantum]; }; QuantumIndexToLP: PROC[qi: QuantumIndex] RETURNS[LONG POINTER] = { n: LONG CARDINAL _ qi; RETURN[LOOPHOLE[n*wordsPerQuantum, LONG POINTER]]; }; IsExtendedBlock: PROC[hp: HeaderP] RETURNS[BOOL] = { RETURN[LOOPHOLE[hp, NHeaderP].blockSizeIndex = bsiEscape]; }; EnumerateCollectableStorage: PUBLIC PROC [callersInfoProc: SweepCollectableStorage.InfoProc] = { done: BOOL _ FALSE; regionCount: INT _ 0 ; ActuallyDoIt: PROC[] RETURNS [userFinished: BOOL] = { hp: HeaderP; blockSize: INT _ 0; FOR hp _ QuantumIndexToLP[currentQuantumStart], hp + blockSize WHILE LOOPHOLE[hp, LONG CARDINAL] < LastAddress AND quantumMap[LPToQuantumIndex[hp]] DO continue: BOOL; nhp: NHeaderP = LOOPHOLE [ IF IsExtendedBlock[hp] THEN hp + SIZE[ExtendedHeader] - SIZE[NormalHeader] ELSE hp, NHeaderP ]; blockSize _ BlockSize[hp]; continue _ callersInfoProc[type: nhp.type, size: blockSize, object: hp, objectHP: nhp]; IF ~continue THEN RETURN[TRUE]; ENDLOOP; IF LOOPHOLE[hp, LONG CARDINAL] >= LastAddress THEN RETURN[FALSE]; RETURN[FALSE]; }; doSweepOfRegion: PROC RETURNS [endOfMemory: BOOL] = { ENABLE UNWIND => NULL; quantumEnd: Allocator.QuantumIndex; userDone: BOOL; haveAllocatorLocked: PROC = { -- here with the loader and allocator locked haveRCOvLocked: PROC = { haveZCTLocked: PROC = { userDone _ ActuallyDoIt[]; }; ZCT.EnterAndCallBack[haveZCTLocked]; }; ZCT.EnterRCOvAndCallBack[haveRCOvLocked]; }; -- end haveAllocatorLocked WHILE ~AllocatorOps.quantumMap[currentQuantumStart] DO IF currentQuantumStart = LAST[QuantumIndex] THEN RETURN[TRUE]; currentQuantumStart _ currentQuantumStart+1; ENDLOOP; quantumEnd _ currentQuantumStart; WHILE AllocatorOps.quantumMap[quantumEnd] AND quantumEnd < LAST[QuantumIndex] DO quantumEnd _ quantumEnd+1; ENDLOOP; VM.SwapIn[interval: [page: currentQuantumStart * Allocator.pagesPerQuantum, count: (quantumEnd - currentQuantumStart ) * Allocator.pagesPerQuantum ]]; AllocatorOps.EnterAndCallBack[haveAllocatorLocked ! UNWIND => {}]; currentQuantumStart _ quantumEnd+1; RETURN[ userDone OR quantumEnd >= LAST[QuantumIndex] ]; }; -- end doSweepOfRegion currentQuantumStart _ FIRST[QuantumIndex]; WHILE ~done DO Process.Pause[1]; done _ doSweepOfRegion[]; regionCount _ regionCount + 1 ; ENDLOOP; }; END. SweepCollectableStorageImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Bob Hagmann, February 19, 1985 5:16:59 pm PST Russ Atkinson (RRA) February 27, 1985 10:51:58 pm PST Variables PROCS this proc visits all collectible objects (free AND allocated) in a region of contiguous VM Find the beginning of the next run of quanta from the quantum map Start parsing at the beginning of this run here with the loader, allocator and RCOvBank locked here with the loader, allocator, RCOvBank and ZCT locked START haveRCOvLocked HERE Acquire the lock on the ref counting machinery, do the work, then release the lock. START haveAllocatorLocked HERE Acquire the lock on the RCOverflowBank, do the work, then release the lock. START doSweepOfRegion HERE First, find and swap in interval needed Next, acquire the lock on the allocator, do the work, then release the lock. Bob Hagmann February 19, 1985 5:06:27 pm PST changes to: DIRECTORY, SweepCollectableStorageImpl, doSweepOfRegion (local of EnumerateCollectableStorage) Κ¬˜codešœ ™ Kšœ Οmœ1™Kšœžœ ˜Kšœ žœ˜Kšœžœ ˜)Kšžœžœ˜Kšžœžœ*˜3K˜—šœž˜$Kšžœžœž˜&Kšžœ˜Kšœžœžœ&˜2K˜šœ ™ K˜Kšœ,˜,K˜—Kšœ™K˜š Οnœžœžœžœžœ˜BKšžœžœžœžœ˜4Kšœ˜K˜—š Ÿœžœžœžœžœ˜BKšœžœžœ˜Kšžœžœžœžœ˜2Kšœ˜K˜—šŸœžœžœžœ˜4Kšžœžœ+˜:Kšœ˜—K˜šŸœžœžœ8˜`Kšœžœžœ˜Kšœ žœ˜šŸ œžœžœžœ˜5šœZ™ZKšœA™A—Kšœ ˜ Kšœ žœ˜Kšœ*™*š žœ<žœžœžœžœžœ"ž˜–Kšœ žœ˜šœ ˜ šœž˜ šœ˜šžœ˜Kšžœžœžœ˜3Kšžœ˜—Kšœ˜—Kšœ˜——Kšœ˜KšœW˜WKšžœ žœžœžœ˜Kšžœ˜—Kšžœžœžœžœžœžœžœ˜AKšžœžœ˜K˜—K˜šΟbœžœžœžœ˜5Kšžœžœžœ˜Kšœ#˜#Kšœ žœ˜š œžœΟc,˜Kš œžœ˜Kšœ3™3š  œžœ˜Kšœ8™8Kšœ˜K˜—šœ™KšœS™S—Kšžœ!˜$K˜—šœ™KšœK™K—Kšžœ&˜)Kšœ‘˜—K™šœ™K™'—šžœ/ž˜6Kš žœžœžœžœžœ˜>Kšœ,˜,Kšžœ˜—Kšœ!˜!šžœ%žœžœž˜PKšœ˜Kšžœ˜—šžœ”˜–KšœL™L—Kšœ4žœ˜BKšœ#˜#Kšžœ žœžœ˜8Kšœ‘œ˜——˜Kšœžœ˜*šžœž˜K˜K˜K˜Kšžœ˜—K˜K˜——Kšžœ˜K˜K˜K˜K˜K˜K˜™,Kšœ Οr7œ'™j—K™—…— ŽJ