DIRECTORY CountedVM USING [Handle, Object], Process USING [Detach, MsecToTicks, Pause], SafeStorage USING [CantEstablishFinalization, EnableFinalization, EstablishFinalization, FinalizationQueue, FQNext, NewFQ, ReclaimCollectibleObjects, ReEstablishFinalization], VM USING [AddressForPageNumber, Allocate, CantAllocate, Free, Interval, LogPageCount, nullInterval, PageCount, PagesForWords, PageNumber, VMPartition]; CountedVMImpl: CEDAR MONITOR IMPORTS Process, SafeStorage, VM EXPORTS CountedVM ~ BEGIN Handle: TYPE ~ CountedVM.Handle; Object: TYPE ~ CountedVM.Object; tries: NAT _ 4; Allocate: PUBLIC PROC [words: INT, partition: VM.VMPartition _ normalVM, subRange: VM.Interval _ [0, 0], start: VM.PageNumber _ 0, alignment: VM.LogPageCount _ 0, in64K: BOOL _ FALSE] RETURNS [h: Handle _ NIL] = { IF words > 0 THEN TRUSTED { count: VM.PageCount ~ VM.PagesForWords[words]; FOR i: NAT IN [0..tries] DO interval: VM.Interval ~ VM.Allocate[count: count, partition: partition, subRange: subRange, start: start, alignment: alignment, in64K: in64K ! VM.CantAllocate => { IF i = tries THEN REJECT; SafeStorage.ReclaimCollectibleObjects[suspendMe: TRUE, traceAndSweep: FALSE]; Process.Pause[Process.MsecToTicks[200]]; LOOP; }]; h _ NEW[Object _ [interval: interval, pointer: VM.AddressForPageNumber[interval.page], words: words]]; SafeStorage.EnableFinalization[h]; EXIT; ENDLOOP; }; }; SimpleAllocate: PUBLIC PROC [words: INT] RETURNS [Handle] = { RETURN[Allocate[words: words]]; }; Free: PUBLIC ENTRY UNSAFE PROC [handle: Handle] = { ENABLE UNWIND => NULL; IF handle # NIL AND handle.pointer # NIL AND handle.words # 0 THEN { interval: VM.Interval _ handle.interval; handle.pointer _ NIL; handle.words _ 0; handle.interval _ VM.nullInterval; TRUSTED {VM.Free[interval]}; }; }; finalizationQueue: SafeStorage.FinalizationQueue _ SafeStorage.NewFQ[]; FinalizationProcess: PROC ~ { DO h: Handle _ NARROW[SafeStorage.FQNext[finalizationQueue]]; TRUSTED {Free[h]}; h _ NIL; ENDLOOP; }; SafeStorage.EstablishFinalization[Object.CODE, 0, finalizationQueue ! SafeStorage.CantEstablishFinalization => { SafeStorage.ReEstablishFinalization[Object.CODE, 0, finalizationQueue]; CONTINUE; }]; TRUSTED {Process.Detach[FORK FinalizationProcess]}; END. 0CountedVMImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Taft, December 10, 1983 3:03 pm Plass, December 21, 1983 1:33 pm Russ Atkinson (RRA) August 22, 1985 5:31:08 pm PDT Doug Wyatt, February 26, 1985 10:20:58 am PST # of times to try to collect extra garbage before giving up There is a possibility that if we could collect some outstanding goodies that we could get enough VM to make all of this work out OK. If we have performed enough GCs, though, we allow the signal to percolate upwards. We can try to free this interval ΚA– "Cedar" style˜codešœ™Kšœ Οmœ1™