<> <> DIRECTORY CollectibleVM, Process USING [Detach], SafeStorage USING [EnableFinalization, EstablishFinalization, FinalizationQueue, FQNext, NewFQ], VM USING [AddressForPageNumber, Allocate, Free, Interval, LogPageCount, PageCount, PageNumber, PageNumberForAddress, PagesForWords, VMPartition, WordsForPages]; CollectibleVMImpl: CEDAR MONITOR IMPORTS Process, SafeStorage, VM EXPORTS CollectibleVM = BEGIN OPEN CollectibleVM; <> New: PUBLIC PROCEDURE [count: VM.PageCount, partition: VM.VMPartition _ normalVM, subRange: VM.Interval _ [0, 0], start: VM.PageNumber _ 0, alignment: VM.LogPageCount _ 0, in64K: BOOL _ FALSE] RETURNS [h: Handle] = BEGIN interval: VM.Interval = VM.Allocate[count: count, partition: partition, subRange: subRange, start: start, alignment: alignment, in64K: in64K]; TRUSTED {h _ NEW[Object _ [DESCRIPTOR[VM.AddressForPageNumber[interval.page], VM.WordsForPages[interval.count]]]]}; SafeStorage.EnableFinalization[h]; END; Free: PUBLIC ENTRY PROCEDURE [h: Handle] = TRUSTED BEGIN IF h^.BASE#NIL THEN BEGIN VM.Free[[page: VM.PageNumberForAddress[h^.BASE], count: VM.PagesForWords[h^.LENGTH]]]; h^ _ [DESCRIPTOR[NIL, 0]]; END; END; <> finalizationQueue: SafeStorage.FinalizationQueue _ SafeStorage.NewFQ[]; FinalizationProcess: PROCEDURE = BEGIN DO h: Handle _ NARROW[SafeStorage.FQNext[finalizationQueue]]; Free[h]; h _ NIL; ENDLOOP; END; <> SafeStorage.EstablishFinalization[Object.CODE, 0, finalizationQueue]; TRUSTED {Process.Detach[FORK FinalizationProcess]}; END.