-- file Alloc.mesa
-- last modified by Bruce, 20-Aug-81 11:14:25
-- last modified by Sweet, 19-Aug-81 12:14:14
-- last modified by Satterthwaite,  2-Oct-81 11:22:26


Alloc: DEFINITIONS = {

  Selector: TYPE = CARDINAL;

  Base: TYPE = LONG ORDERED BASE POINTER;
  Limit: CARDINAL = LAST[CARDINAL];
  Index: TYPE = Base RELATIVE POINTER [0..Limit);
  OrderedIndex: TYPE = Base RELATIVE ORDERED POINTER [0..Limit);

  Handle: TYPE = LONG POINTER TO InstanceData;
  InstanceData: TYPE;
  
 -- allocation from the tables as stacks

  Words: PROC [h: Handle, table: Selector, size: CARDINAL] RETURNS [OrderedIndex];
  Trim: PROC [h: Handle, table: Selector, size: CARDINAL];

 -- allocation from free list 

  defaultChunkType: Selector = FIRST[Selector];
  
  GetChunk: PROC [h: Handle, size: CARDINAL, table: Selector ← defaultChunkType] RETURNS [Index];
  FreeChunk: PROC [h: Handle, index: Index, size: CARDINAL, table: Selector ← defaultChunkType];

 -- inquiries
  
  Bounds: PROC [h: Handle, table: Selector] RETURNS [base: Base, size: CARDINAL];
  Top: PROC [h: Handle, table: Selector] RETURNS [OrderedIndex] = INLINE {
    RETURN[FIRST[OrderedIndex] + h.Bounds[table].size]};

 -- inquiries and notification of moving subtables
  
  Notifier: TYPE = PROC [base: LONG DESCRIPTOR FOR ARRAY Selector OF Base];

  AddNotify: PROC [h: Handle, proc: Notifier];
  DropNotify: PROC [h: Handle, proc: Notifier];

 -- initialization and termination
  
  maxForBits: ARRAY [1..16] OF CARDINAL = [
        1b,      3b,      7b,     17b,     37b,     77b,    177b,    377b,
      777b,   1777b,   3777b,   7777b,  17777b,  37777b,  77777b, 177777b];
  pagesForBits: ARRAY [1..16] OF CARDINAL = [
      1,   1,   1,   1,   1,   1,   1,   1,
      2,   4,   8,  16,  32,  64, 128, 256];
	 
  defaultIndexBits: CARDINAL = 14;
  defaultTileSize: CARDINAL = 8;
  
  TableInfo: TYPE = RECORD [
    initialPages: [0..377b], 
    variant: SELECT useFullVmem: BOOLEAN FROM
      FALSE => [initialVMemPages: [0..177b]],
      TRUE => [],
      ENDCASE ← TRUE[]];
  
  Create: PROC [
      weights: DESCRIPTOR FOR ARRAY OF TableInfo,
      indexBits: CARDINAL ← defaultIndexBits,
      tileSize: CARDINAL ← defaultTileSize] 
    RETURNS [Handle];
  Destroy: PROC [Handle];
  Reset: PROC [Handle];
  
  Chunkify: PROC [
    h: Handle, table: Selector ← defaultChunkType, 
    firstSmall: CARDINAL ← 3, nSmall: CARDINAL ← 4];
  UnChunkify: PROC [h: Handle, table: Selector];
  ResetChunk: PROC [h: Handle, table: Selector];

  ResetTable: PROC [h: Handle, table: Selector, info: TableInfo];

  Failure: ERROR [h: Handle, table: Selector];
  Overflow: SIGNAL [h: Handle, table: Selector] RETURNS [extra: CARDINAL];

  }.