-- SafeStorage.Mesa
-- last edited May 27, 1982 12:51 pm by Paul Rovner

DIRECTORY
  RTBasic USING[Base, nullBase, Type];

SafeStorage: CEDAR DEFINITIONS
= BEGIN OPEN RTBasic;

 -- For managing ZONEs

  SizeRepresentation: TYPE = {quantized, prefixed};

  NewZone: PROC
            [ sr: SizeRepresentation ← prefixed,
              base: Base ← nullBase,  -- default will use the RootBase
              initialSize: LONG CARDINAL ← 0  -- words
            ] RETURNS[ZONE];

  TrimZone: PROC[zone: ZONE];
    -- return unused quanta to zone's Base

  TrimAllZones: PROC;
    -- applies TrimZone to each ZONE

  MergeAllPrefixedZones: PROC;
    -- for each prefixed ZONE, merge adjacent free blocks by scanning its free list

  IsZoneEmpty: PROC[zone: ZONE] RETURNS[BOOLEAN];
    -- TRUE if no quanta are assigned to zone

  GetSystemZone: PROC RETURNS[ZONE];  -- a built-in, prefixed ZONE in baseRoot


 -- For controlling the garbage collector

        -- establishes the number of cells allocated between collections
  SetCollectionInterval: PROC[newInterval: LONG CARDINAL--words--]
        RETURNS[previous: LONG CARDINAL];

        -- establishes a maximum amount of VM that can be assigned to
	-- the Cedar allocators: when this threshold is crossed,
	-- a collection that trims all zones and the root Base will
	-- occur. 0 => no limit enforced by the Cedar allocators.
  SetMaxDataQuanta: PROC[nQuanta: CARDINAL--4 pages per quantum--]
        RETURNS[previous: CARDINAL];

        -- perform a garbage collection
  ReclaimCollectibleObjects: PROC[suspendMe: BOOLEAN ← TRUE,
                                  traceAndSweep: BOOLEAN ← FALSE];


 -- For monitoring the garbage collector

  ReclamationReason: TYPE =
           {clientRequest, clientTAndSRequest, clientNoTraceRequest,
	    rcTableOverflow, allocationInterval, quantaNeeded,
	    finalizationThreshold};

  IsCollectorActive: PROC RETURNS[active: BOOLEAN, previousIncarnation: CARDINAL];

  WaitForCollectorStart: PROC
    RETURNS[incarnation: CARDINAL,
            reason: ReclamationReason,
            wordsAllocated: LONG CARDINAL,
	      -- since previous collection was initiated
            objectsAllocated: LONG CARDINAL];

  WaitForCollectorDone: PROC
    RETURNS[incarnation: CARDINAL,
            reason: ReclamationReason,
            wordsReclaimed: LONG CARDINAL,
            objectsReclaimed: LONG CARDINAL];
 

 -- Statistics

  NWordsAllocated: PROC RETURNS[LONG CARDINAL];  -- returns total # words allocated so far
  NWordsReclaimed: PROC RETURNS[LONG CARDINAL];  -- returns total # words reclaimed so far


 -- Bases

  NewBase: PROC[nWords: LONG CARDINAL, baseParent: Base ← nullBase] RETURNS[Base];

  GetRootBase: PROC RETURNS[Base];

  TrimRootBase: PROC RETURNS[nSpacesDeleted: CARDINAL];


 -- Unusual operations on ZONEs for sophisticated clients

  ZoneFullProc: TYPE = PROC[zone: ZONE, size: LONG CARDINAL--words--];

  ExtendZone: ZoneFullProc;

  SetZoneFullProc: PROC -- the default "FullProc" is ExtendZone
            [ zone: ZONE, 
              proc: ZoneFullProc
            ] RETURNS[previous: ZoneFullProc];


-- SIGNALs and ERRORs

  InvalidSize: ERROR[size: LONG CARDINAL];  -- Raised by NewBase, NewZone, ExtendZone
  MemoryExhausted: ERROR[base: Base];
  NarrowFault: ERROR;
  NarrowRefFault: ERROR[ref: REF ANY, targetType: Type];
  UnsafeProcAssignment: SIGNAL[proc: PROC ANY RETURNS ANY];

END.