<> <> SafeStorage: CEDAR DEFINITIONS = BEGIN <> TrimSystemZone: PROC; <> GetSystemZone: PROC RETURNS[ZONE]; <> GetPermanentZone: PROC RETURNS[ZONE]; <> <> SetCollectionInterval: PROC[newInterval: INT--words--] RETURNS[previous: INT]; <> ReclaimCollectibleObjects: PROC[suspendMe: BOOL _ TRUE, traceAndSweep: BOOL _ FALSE]; <> <> ReclamationReason: TYPE = {clientRequest, clientTAndSRequest, clientNoTraceRequest, rcTableOverflow, allocationInterval, quantaNeeded, finalizationThreshold}; IsCollectorActive: PROC RETURNS[active: BOOL, previousIncarnation: INT]; WaitForCollectorStart: PROC RETURNS[ incarnation: INT, reason: ReclamationReason, wordsAllocated: INT, --since previous collection was initiated objectsAllocated: INT]; WaitForCollectorDone: PROC RETURNS[ incarnation: INT, reason: ReclamationReason, wordsReclaimed: INT, objectsReclaimed: INT]; <<>> <> NWordsAllocated: PROC RETURNS[INT]; -- returns total # words allocated NWordsReclaimed: PROC RETURNS[INT]; -- returns total # words reclaimed <<>> <> <]>> TypeIndex: TYPE = [0..LAST[CARDINAL]/4]; -- 14 bits Type: TYPE = RECORD[TypeIndex]; <> nullType: Type = [0]; unspecType: Type = [1]; -- the distinguished type of UNSPECIFIED fhType: Type = [2]; -- the distinguished type of localFrames gfhType: Type = [3]; -- the distinguished type of globalFrames anyType: Type = [4]; -- the distinguished type of ANY lastPredefinedTypeIndex: TypeIndex = 4; <> GetCanonicalReferentType: PROC[ref: REF ANY] RETURNS[type: Type]; EquivalentTypes: PROC[t1, t2: Type] RETURNS[BOOL]; GetCanonicalType: PROC[type: Type] RETURNS[Type]; IsReferentType: PROC[ref: REF ANY, type: Type] RETURNS[BOOL]; NarrowRef: PROC[ref: REF ANY, type: Type] RETURNS[REF ANY]; <> <> <> <<1. Establish finalization for a type BEFORE applying EnableFinalization to objects of the type.>> <<2. Invoke EnableFinalization AFTER establishing the package refs to the new object.>> <<3. Do not nilify the package refs to an object while IsFinalizationEnabled[objRef].>> <<>> <> <<>> <<*** START OF EXAMPLE>> <<>> <<--START CODE>> <> <<>> <, fq: myQueue];>> <> <<>> <<--Find a cache entry for key>> <> < NULL;>> <<>> <> <> <> <>> <> <<--Make a new one and enter it in the hash table>> <> <<>> <<--now enable the object for insertion on myQueue when the collector finds that no client references to it exist.>> <<--This also marks the object as (re)issued.>> <> <<-- no-op if IsFinalizationEnabled[handle]>> <<};>> <<>> <> <> <<};>> <<>> < NULL;>> <> <> <<};>> <<>> <<*** END OF EXAMPLE>> <<>> maxNPackageRefs: CARDINAL = 2; FinalizationQueue: TYPE = PRIVATE RECORD[REF ANY]; EstablishFinalization: PROC[type: Type, npr: [0..maxNPackageRefs], fq: FinalizationQueue]; <> ReEstablishFinalization: PROC[type: Type, npr: [0..maxNPackageRefs], fq: FinalizationQueue]; <> <> EnableFinalization: PROC[ref: REF ANY]; <> IsFinalizationEnabled: PROC[ref: REF ANY] RETURNS[BOOL]; <> NewFQ: PROC[length: CARDINAL _ 10--refs--] RETURNS[FinalizationQueue]; FQNext: PROC[fq: FinalizationQueue] RETURNS[REF ANY]; -- waits 'till there is one FQEmpty: PROC[fq: FinalizationQueue] RETURNS[BOOL]; <<>> <> PutTypeAttachment: PROC[type: Type, attachment: REF ANY]; GetTypeAttachment: PROC[type: Type] RETURNS[REF ANY]; <> MemoryExhausted: ERROR; NarrowFault: ERROR; NarrowRefFault: ERROR[ref: REF ANY, targetType: Type]; UnsafeProcAssignment: SIGNAL[proc: PROC ANY RETURNS ANY]; InvalidType: ERROR[type: Type]; CantEstablishFinalization: ERROR[type: Type]; END.