<> <> <> <> DIRECTORY AllocatorOps USING[permanentPageZone], Collector USING[InternalReclaim], PrincOps USING[PsbIndex], Process USING[GetCurrent], StorageAccounting USING[defaultCollectionInterval, PSBIMap], SafeStorage USING[]; StorageAccountingImpl: MONITOR -- Protects the storage account books IMPORTS AllocatorOps, Collector, Process EXPORTS StorageAccounting, SafeStorage = BEGIN OPEN StorageAccounting; <<>> <<>> <> nWordsRequested: PUBLIC INT _ 0; nWordsAllocated: PUBLIC INT _ 0; -- >= CollectionInterval implies collect SUMnWordsAllocated: PUBLIC INT _ 0; nWordsReclaimed: PUBLIC INT _ 0; nObjectsCreated: PUBLIC INT _ 0; nObjectsReclaimed: PUBLIC INT _ 0; MapPsbiToWordsAllocated: PUBLIC LONG POINTER TO StorageAccounting.PSBIMap; CollectionInterval: PUBLIC INT _ StorageAccounting.defaultCollectionInterval; SuspensionThreshold: PUBLIC INT _ ComputeSuspensionThreshold[]; <<>> <<>> <> ComputeSuspensionThreshold: PROC RETURNS[LONG INTEGER] = { RETURN[CollectionInterval+CollectionInterval]}; NWordsAllocated: PUBLIC --to SS-- ENTRY SAFE PROC RETURNS[INT] = TRUSTED { ENABLE UNWIND => NULL; RETURN[SUMnWordsAllocated + nWordsAllocated]; }; NWordsReclaimed: PUBLIC --to SS-- SAFE PROC RETURNS[INT] = TRUSTED { RETURN[nWordsReclaimed]; }; ConsiderCollection: PUBLIC PROC[requestedWords, suppliedWords: LONG CARDINAL] = { psbi: PrincOps.PsbIndex = LOOPHOLE[Process.GetCurrent[]]; nw: LONG INTEGER _ MapPsbiToWordsAllocated.elements[psbi].current + suppliedWords; MapPsbiToWordsAllocated.elements[psbi].current _ nw; nWordsAllocated _ nWordsAllocated + suppliedWords; <> nWordsRequested _ nWordsRequested + requestedWords; -- total count for all processes IF LOOPHOLE[nWordsAllocated, INT] >= CollectionInterval OR nw > SuspensionThreshold THEN Collector.InternalReclaim[allocationInterval, nw > SuspensionThreshold]; }; SetCollectionInterval: PUBLIC --to SS-- ENTRY SAFE PROC[newInterval: LONG CARDINAL] RETURNS[oldInterval: LONG CARDINAL] = TRUSTED { ENABLE UNWIND => NULL; oldInterval _ CollectionInterval; CollectionInterval _ newInterval; SuspensionThreshold _ ComputeSuspensionThreshold[]; }; ResetNWordsAllocated: PUBLIC ENTRY PROC = { ENABLE UNWIND => NULL; SUMnWordsAllocated _ SUMnWordsAllocated + nWordsAllocated; nWordsAllocated _ 0; FOR i: PrincOps.PsbIndex IN PrincOps.PsbIndex DO MapPsbiToWordsAllocated.elements[i].total _ MapPsbiToWordsAllocated.elements[i].total + MapPsbiToWordsAllocated.elements[i].current; MapPsbiToWordsAllocated.elements[i].current _ 0; ENDLOOP; }; ResetTotalNWordsAllocatedOnly: PUBLIC ENTRY PROC = { SUMnWordsAllocated _ SUMnWordsAllocated + nWordsAllocated; nWordsAllocated _ 0; }; <<>> <<>> <> MapPsbiToWordsAllocated _ AllocatorOps.permanentPageZone.NEW[ StorageAccounting.PSBIMap[LAST[PrincOps.PsbIndex]+1]]; FOR i: PrincOps.PsbIndex IN PrincOps.PsbIndex DO MapPsbiToWordsAllocated.elements[i] _ [total: 0, current: 0]; ENDLOOP; END.