home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 375.lha / IncrStorageManager_v1.0 / DynamicItem.def < prev    next >
Text File  |  1990-05-02  |  6KB  |  157 lines

  1. DEFINITION MODULE DynamicItem;
  2.  
  3. (* Product: Incremental Storage Manager
  4.  
  5.    Version: 1.0
  6.  
  7.    Author:
  8.         Daniel B. Hankins
  9.         143 Montgomery Street
  10.         Poughkeepsie, NY 12601
  11.         dan-hankins@cup.portal.com
  12.  
  13.    Creation Date: 1989
  14.  
  15.    Release  Date: November 21, 1989
  16.  
  17.    Notice of Intellectual Property:
  18.         This material is *NOT COPYRIGHTED*.  By this notice, I hereby place
  19.    this program and all its parts in the public domain, under the definitions
  20.    and restrictions of United States law.
  21.  
  22.    History of Revisions:
  23.         None yet.
  24. *)
  25.  
  26. FROM SYSTEM IMPORT ADDRESS;
  27.  
  28. TYPE
  29.   Object;
  30.  
  31.   InitProc = PROCEDURE(ADDRESS);
  32.   TermProc = InitProc;
  33.  
  34. PROCEDURE New(Size: LONGCARD; InitIt: InitProc; TermIt: TermProc): Object;
  35. (* Size:   *in*  Size in bytes of chunk to be allocated
  36.    InitIt: *in*  The procedure which will initialize the contents of the
  37.                  chunk.  It is passed the address of the first byte of the
  38.                  chunk.
  39.    TermIt: *in*  The procedure which will clean up the contents of the
  40.                  chunk when its storage is reclaimed.  For instance, if
  41.                  the chunk contains variables of type DynamicItem.Object,
  42.                  TermIt should DynamicItem.Dispose each of them so that
  43.                  their reference counts can be accurately maintained.
  44.            *out* The resulting object
  45. *)
  46.  
  47. PROCEDURE Ref(Item: Object): Object;
  48. (* Item: *in*  The chunk to which another reference is to be generated.
  49.          *out* The chunk after its reference count is incremented.
  50.  
  51.    Explanations and Recommendations:
  52.         Although the Modula-2 compiler will allow the programmer to perform
  53.    assignment between variables of type DynamicItem.Object, she should not.
  54.    This storage manager relies on a technique called reference counts.  The
  55.    reference count (which is embedded in the header of a storage chunk) is
  56.    intended to reflect the number of variables (pointers, actually) which
  57.    are accessing the same chunk.  The reason for this is so that the
  58.    storage manager will know when it can remove the chunk from the active
  59.    list and reclaim the storage it consumed.
  60.         So if variables A, B, and C are all of type DynamicItem.Object, and
  61.    all reference the same storage chunk, then the reference count of the
  62.    chunk should be three.
  63.         To make two variables refer to the same object, use the following:
  64.  
  65.         A := DynamicItem.Ref(B);
  66.  
  67.    instead of
  68.  
  69.         A := B;
  70.  
  71.         If you want to copy the contents of an chunk A into another chunk
  72.    B, then the programmer should create a new dynamic item object B, access
  73.    the contents of both, and then copy the contents.  For instance:
  74.  
  75.         B := DynamicItem.New(ASize, AInit, ATerm);
  76.         ACopy(DynamicItem.Access(A), DynamicItem.Access(B));
  77.  
  78.    where ACopy takes a pair of pointers to the kind of chunk being copied.
  79. *)
  80.  
  81.  
  82. PROCEDURE Dispose(Item: Object);
  83. (* Item: *in* The chunk to be disposed of.
  84.  
  85.    Explanations and Recommendations:
  86.         Dispose does *not* necessarily reclaim the storage used by a chunk.
  87.    Dispose decrements the reference count of the chunk (see procedure Ref,
  88.    above); there is now one less pointer to the chunk.  Only when there are
  89.    no pointers left to a chunk (i.e. reference count = 0) does Dispose
  90.    actually attempt to reclaim the storage used by the chunk.  Just
  91.    before reclaiming that storage, it runs the TermIt procedure (see
  92.    procedure New, above) stored in the header of the chunk against the
  93.    contents of that chunk.  The TermIt procedure is meant to be used for
  94.    Dispose-ing of any chunks the chunk may reference.
  95.         For instance, suppose that the chunk the programmer is working
  96.    with is a record which has three variables of type DynamicItem.Object.
  97.    TermIt should DynamicItem.Dispose each of the three variables.
  98.    Otherwise, the three chunks referenced will *never* be reclaimed;
  99.    their reference counts will never go to zero, and they will become
  100.    unusable dead storage.
  101. *)
  102.  
  103. PROCEDURE Access(Item: Object): ADDRESS;
  104. (* Item: *in*   The chunk which is to be accessed.
  105.          *out*  The address of the contents of the chunk.
  106.  
  107.    Explanations and Recommendations:
  108.         Whenever DynamicItem.New or DynamicItem.Dispose is called,
  109.    the contents of a chunk may move in memory.  So it is a good idea to
  110.    avoid code like this:
  111.  
  112.         ChunkPtr := DynamicItem.Access(ChunkVar);
  113.         ...
  114.         (* other code *)
  115.         ...
  116.         DynamicItem.Dispose(ChunkVar2);
  117.         ChunkPtr^.XValue := 10;
  118.  
  119.    because ChunkPtr may no longer be pointing at the contents of the
  120.    chunk after a New or Dispose is done.  A better practice is to
  121.    *always* Access a chunk *just before* its contents are to be
  122.    manipulated, like this:
  123.  
  124.         ChunkPtr := DynamicItem.Access(ChunkVar);
  125.         ...
  126.         (* other code *)
  127.         ...
  128.         DynamicItem.Dispose(ChunkVar2);
  129. >>>     ChunkPtr := DynamicItem.Access(ChunkVar);
  130.         ChunkPtr^.XValue := 10;
  131. *)
  132.  
  133. PROCEDURE Set(Item:Object; NewDynItem: ADDRESS);
  134. (* DO NOT USE THIS PROCEDURE; IT IS FOR THE EXCLUSIVE USE OF OTHER PARTS
  135.    OF THE STORAGE MANAGER!
  136. *)
  137.  
  138. PROCEDURE DisposeAll();
  139. (* This procedure returns *all* storage allocated by the storage manager
  140.    to the operating system.  It is a good idea to call this procedure
  141.    just before exiting your program;  it makes sure you haven't forgotten
  142.    to return any resources you've used.
  143. *)
  144.  
  145. PROCEDURE NilObject(): Object;
  146. (* This procedure returns an uninitialized chunk, which cannot be used
  147.    except for testing to see if another chunk is uninitialized.  It is
  148.    primarily for use of other storage manager procedures.
  149. *)
  150.  
  151. PROCEDURE Nil(Item: Object): BOOLEAN;
  152. (* This procedure returns TRUE if a chunk is uninitialized, FALSE 
  153.    otherwise.
  154. *)
  155.  
  156. END DynamicItem.
  157.