![]() |
Home · Pages · Index · Overviews |
Generic Class Routines Module ReferenceThe operations common to every class. More... Routines
Detailed DescriptionMylib employs a consistent object-oriented style, and every class, say X, has routines to perform the set of function described on this page, with the possible exception of the read and write routines if objects of the class are intrinsically short-lived (e.g. a Slice or Frame). The routines are primarily concerned with object and memory management. Each Mylib class keeps track of the set of objects of the class, and every object keeps a reference count of the number of program variables and Mylib objects that refer to it. Every class also keeps a cache or free pool of previously used objects that it can redeploy as requested, and every object can be thought of as a container that holds a value that may not actually occupy all the memory of the container. These features, to be explained more precisely in the following, permit Mylib users to avoid excessive use of the system heap, if they so desire. A very detailed treatment of object management in Mylib is given in the document Object.Management. The first section of the document describes the object-oriented conventions and associated routines. For those wishing to add new classes to Mylib, the second section describes how to generate the code for these standard routines from a single specification line and a number of small helper routines using a preprocessor built specifically for this purpose. The final section precisely documents the code generated for these routines for those who are interested or want to extend the object management conventions. In what follows we give a fairly terse explanation of the semantics of each routine. An object of class X can be copied with Copy_X which generates a new copy of the object that has a reference count of 1. Every object has a reference count that can be incremented by calling Inc_X, examined by calling X_Refcount, and decremented by calling either Free_X or Kill_X. Any newly generated object has an initial reference count of 1. If a subsequent call to Free_X or Kill_X reduces the reference count to 0, then the object is returned to the system heap if Kill_X was called, or to a free pool maintained by the class if Free_X was called. The idea of this free pool, is to allow a user to optimize the frequent case where one has a loop in which one creates an object, operates upon it, and then no longer needs it. For example, consider for (i = 0; i < N; i++) { Array *a = Read_Array(input); // Do something with a Kill_Array(a); } versus for (i = 0; i < N; i++) { Array *a = Read_Array(input); // Do something with a Free_Array(a); } In the kill case, 4N calls to malloc and free of the underlying system heap are made (4 per array). In the free case, the Array object is recirculated through the Array class's free pool, so realloc is called only when the next array is bigger in some aspect (its dims, text, or data) then the previous array. In the oft-occuring case where the arrays are all of the same size, no use of the system heap is required at all after the first iteration. In the case where the size of each array is random, in expectation O(log N) realloc calls are performed. In most cases, the user knows the pattern of creation and destruction of objects, so by using Free_X appropriately they can save time and prevent the system memory allocator from getting into a fragmented state that can cause it to thrash. Because of the recycling enabled by Free_X, over time such a reused object container can become significantly bigger than the value it stores (e.g. the next read in our running example brings in a small array whose value is placed in the single Array object that is being recycled). Calling Pack_X will shrink the container of an object of class X so that the memory occupied by its container is just large enough to hold the object's value. Calling Reset_X will (a) return every object currently in the free pool back to the system heap, and (b) free any working storage that might be used by the class. The effect is to effectively return the class to its original state. To help programmers avoid memory leaks, X_Usage returns the number of objects currently in use by the programmer (i.e. those that have been generated and have neither been returned to the system heap or placed in the free pool). To further aid a programmer, X_List calls a handler on each object that the class still thinks are in use. As an example, if one wanted to ensure that a class was in its original state, one would write: void KillEmAll(X *x) { Kill_X(x); } X_List(KillEmAll); Reset_X(); Routine Documentation
Generate and return a new object with reference count 1 whose value is identical to that of x.
Increment the reference count of x by 1.
Return the current reference count of object x.
Decrement the reference count of object x and if it reaches 0, then move the object to the free pool of class X.
Decrement the reference count of object x and if it reaches 0, then return all the memory blocks of an object to the system heap.
If the container of x (the set of all memory blocks holding the value of x), is larger than necessary, then shrink it (via calls to realloc on the relevant memory blocks) so that it is just large enough to hold the current value of x.
Kill, i.e. return to the system heap, all objects in the free pool of class X, and free all working storage that might be used by the routines of the object. The latter depends on and is specific to the class in question.
Return the number of objects of class X that have been created and as yet neither returned to the free pool of X or system heap.
Call handler on each object of the class X that have been created and as yet neither returned to the free pool of X or system heap.
Generate an object of class X and set it to a value read from the file stream input. The read begins at the current file position indicator of input and should be an encoding of a value of an object of type X that is produced by Write_X. The file position indicator is advanced to the next byte after the encoded value on the stream input.
Write an encoding of the value of x on the file stream output starting at the current file position indicator of output. The file position indicator is advanced to the next byte after the encoded value on the stream input. |