pfMemory(3pf) OpenGL Performer 3.2.2 libpr C++ Reference Pages pfMemory(3pf)NAME
pfMemory, pfStrdup - Reference, copy, delete, print and query pfMemoryFUNCTION SPECIFICATION
#include <Performer/pr/pfMemory.h>
pfMemory::pfMemory();
void* pfMemory::operator new(size_t, size_t nbytes);
void* pfMemory::operator new(size_t, size_t nbytes,
void *arena);
void* pfMemory::operator new(size_t, size_t nbytes,
pfFluxMemory *fmem);
static pfType * pfMemory::getClassType(void);
void* pfMemory::getData(const void *ptr);
static void* pfMemory::getData(const void *ptr);
pfType * pfMemory::getType();
static pfType * pfMemory::getType(const void *ptr);
int pfMemory::isOfType(pfType *type);
static int pfMemory::isOfType(const void *ptr, pfType *type);
int pfMemory::isExactType(pfType *type);
static int pfMemory::isExactType(const void *ptr,
pfType *type);
const char * pfMemory::getTypeName();
static const char * pfMemory::getTypeName(const void *ptr);
int pfMemory::copy(pfMemory *src);
static int pfMemory::copy(void *dst, void *src);
int pfMemory::compare(const pfMemory *mem);
static int pfMemory::compare(const void *ptr1,
const void *ptr2);
void pfMemory::print(uint which, uint verbose,
char *prefix, FILE *file);
Page 1
pfMemory(3pf) OpenGL Performer 3.2.2 libpr C++ Reference Pages pfMemory(3pf)
static void pfMemory::print(const void *ptr, uint which,
uint verbose, FILE *file);
int pfMemory::getArena(void *ptr);
void* pfMemory::getArena();
static void* pfMemory::getArena(void *ptr);
int pfMemory::ref();
static int pfMemory::ref(void *ptr);
int pfMemory::unref();
static int pfMemory::unref(void *ptr);
int pfMemory::unrefDelete();
static int pfMemory::unrefDelete(void *ptr);
int pfMemory::unrefGetRef();
static int pfMemory::unrefGetRef(void *ptr);
int pfMemory::getRef();
static int pfMemory::getRef(const void *ptr);
int pfMemory::checkDelete();
static int pfMemory::checkDelete(void *ptr);
int pfMemory::isFluxed();
static void * pfMemory::malloc(size_t nbytes, void *arena);
static void * pfMemory::calloc(size_t numelem, size_t elsize,
void *arena);
void * pfMemory::realloc(size_t nbytes);
static void * pfMemory::realloc(void *ptr, size_t nbytes);
static void pfMemory::free(void *ptr);
void * pfMemory::getArena();
static void * pfMemory::getArena(void *ptr);
Page 2
pfMemory(3pf) OpenGL Performer 3.2.2 libpr C++ Reference Pages pfMemory(3pf)
int pfMemory::getSize();
static int pfMemory::getSize(void *ptr);
static int pfMemory::getArenaBytesUsed();
char * pfStrdup(const char *str, void *arena);
DESCRIPTIONpfMemory is the base class from which all major OpenGL Performer classes
are derived and is also the type used by the OpenGL Performer memory
allocation routines such as pfMemory::malloc and pfMemory::free.
Because most OpenGL Performer data structures are derived from pfMemory,
they inherit the functionality of the pfMemory routines described here.
In practice this means you can use the pfMemory routines listed above
with most any OpenGL Performer object, such as pfMaterial, pfList, pfFog,
pfFrustum, pfChannel, pfGroup, pfGeode or with a data pointer returned by
pfMemory::malloc.
pfMemory supports the following:
1. Typed data structures.
2. Memory arena allocation.
3. Memory chunks which know their size.
4. Reference counting.
with only a 4 word overhead.
Although the OpenGL Performer general memory allocation routines (-
pfMemory::malloc) create pfMemories, they return void* so the application
can treat the allocation as raw data. Consequently, all routines that
would normally take a pfMemory* take a void* and infer the pfMemory
handle so that applications can treat pfMemory as raw memory. However,
one caveat is that routines which take raw memory such as
pfGeoSet::setAttr or pfMemory::free should not be passed a pointer to
static data since the routines may not be able to successfully infer the
pfMemory handle from the void*.
--------------- <------ pfMemory*
| pfMemory |
| header |
| |
--------------- <------ void* returned by
| | allocation routines
| raw data |
. .
. .
Page 3
pfMemory(3pf) OpenGL Performer 3.2.2 libpr C++ Reference Pages pfMemory(3pf)
. .
| |
---------------
Routines which convert between pfMemory* and void* are:
void* -> pfMemory*: pfMemory::getMemory
pfMemory* -> void*: pfMemory::getData
Note that is it legal to pass either a pfMemory* or a void* to those
routines which are prototyped as accepting a void*, e.g., pfMemory::ref.
In this way, a single set of routines supports the same feature set
including reference counts, copy, and delete for pfMemories used as
OpenGL Performer data types like pfGeoSet as well as for pfMemories used
as raw data like pfGeoSet attribute arrays.
pfMemory::getClassType returns the pfType* for the class pfMemory. The
pfType* returned by pfMemory::getClassType is the same as the pfType*
returned by invoking the virtual function getType on any instance of
class pfMemory. Because OpenGL Performer allows subclassing of built-in
types, when decisions are made based on the type of an object, it is
usually better to use the member function isOfType to test if an object
is of a type derived from a Performer type rather than to test for strict
equality of the pfType*'s.
All objects derived from pfMemory have a type identifier (pfType*) that
is returned by the member function getType. Most Performer types are
derived from other Performer types with the derived type taking on the
functionality and routines associated with its parent type. This type
inheritance allows routines associated with a type to be used with any
types derived from it. For example pfDCS is derived from pfGroup.
Example 1: API sharing.
dcs = new pfDCS;
/* pfDCS uses pfGroup routine */
dcs->addChild(geode);
/* pfDCS uses pfNode routine */
dcs->setTravMask(PFTRAV_ISECT, DCS_MASK, PFTRAV_SELF | PFTRAV_DESCEND, PF_SET);
Each data type derived from pfMemory has an associated routine for
getting a pointer to its corresponding pfType, e.g.
pfDCS::getClassType() returns the pfType* corresponding to the pfDCS
class. The exact type of an object is tested by comparing its pfType* to
Page 4
pfMemory(3pf) OpenGL Performer 3.2.2 libpr C++ Reference Pages pfMemory(3pf)
that returned by one of these *::getClassType routines or with the
pfMemory::isExactType test, e.g.
if (obj->getType == pfGroup::getClassType()) ...
if (obj->IsExactType(pfGroup::getClassType())) ...
But since OpenGL Performer allows subclassing and the creation of new
types in C++, it's more often desirable to know whether a particular
object is of a type derived from a particular type defined by OpenGL
Performer. In particular, exact type tests makes application code more
likely to fail on scene graphs produced by database loaders that use
subclassing. pfMemory::isOfType performs this test and returns TRUE if
the object's type is derived from type:
if (obj->isOfType(pfGroup::getClassType())) ...
If 'obj' is a pfDCS, then the above conditional would evaluate TRUE since
pfDCS is derived from pfGroup.
pfMemory::getTypeName returns a string that identifies the type of the
object. For example, if the object is a pfDCS, the string returned is
"pfDCS".
All pfMemories have a reference count which indicates how many times the
pfMemory is referenced, either by other pfMemories or by the application.
Reference counts are crucial for many database operations, particularly
deletion, since it is highly dangerous to delete a pfMemory which is
still being used, i.e., its reference count is greater than 0.
Reference counts may be incremented and decremented by pfMemory::ref and
pfMemory::unref respectively. pfMemory::getRef returns the reference
count of the object. pfMemory::unrefGetRef decrements the reference
count and returns the new value, as an atomic operation, i.e. it is
guaranteed that no other process can change the value or free the memory
between the decrement and the time the value is read.
pfBuffer::unrefDelete will decrement the reference count of the object
and delete it if the count is <= 0. Thus it is equivalent to calling
pfMemory::unref followed by pfBuffer::checkDelete, as an atomic
operation.
pfMemory::checkDelete frees the memory associated with the object if its
reference count is <= 0. When an object is freed, it decrements the
reference count of all pfMemories that it once referenced and will delete
any of these pfMemories with reference counts that are <= 0. Thus,
pfBuffer::checkDelete will follow all reference chains until it
encounters a pfMemory which it cannot delete. Note that the reference
Page 5
pfMemory(3pf) OpenGL Performer 3.2.2 libpr C++ Reference Pages pfMemory(3pf)
count of a pfNode is incremented each time it is added as a child to a
pfGroup. Thus, a pfNode must be removed from all its parents before it
can be deleted.
When multiprocessing in a libpf application, pfNodes should be pfDeleteed
only in the APP or DBASE processes as should libpr objects that are
referenced directly or indirectly by pfNodes, like pfGeoSets and
pfGeoStates. If you wish to delete objects in processes other than the
APP or DBASE, use pfAsyncDelete.
Example 2: Deletion
pfMaterial *mtl;
pfTexture *tex;
pfGeoState *brickStyle, *woodStyle;
pfGeoSet *brickWall, *woodWall;
mtl = new pfMaterial;
brickStyle = new pfGeoState;
tex = new pfTexture;
tex->loadFile("brick.rgb");
brickStyle->setAttr(PFSTATE_TEXTURE, tex);
brickStyle->setAttr(PFSTATE_FRONTMTL, mtl);
woodStyle = new pfGeoState;
tex = new pfTexture;
tex->loadFile("wood.rgb");
woodStyle->setAttr(PFSTATE_TEXTURE, tex);
woodStyle->setAttr(PFSTATE_FRONTMTL, mtl);
brickWall = new pfGeoSet;
brickWall->setGState(brickStyle);
brickWall->setAttr(PFGS_COORD3, PFGS_PER_VERTEX, coords);
woodWall = new pfGeoSet;
woodWall->setGState(woodStyle);
woodWall->setAttr(PFGS_COORD3, PFGS_PER_VERTEX, coords);
delete woodWall;
/* At this point woodWall, woodStyle, and the wood texture
* have been deleted. coords and mtl have not been deleted
* since they are referenced by brickWall and brickStyle respectively.
*/
pfBuffer::checkDelete returns the following:
Page 6
pfMemory(3pf) OpenGL Performer 3.2.2 libpr C++ Reference Pages pfMemory(3pf)
FALSE the object was not deleted
TRUE the object was deleted
-1 the object is not a pfMemory
pfBuffer::checkDelete is implemented for all OpenGL Performer objects
except the following:
pfPipe
pfChannel
pfEarthSky
pfBuffer
pfPipeWindow
pfTraverser
pfState
pfDataPool
pfMemory::isFluxed returns TRUE if a pfMemory is actually the data
portion of a pfFluxMemory that is part of a pfFlux. It returns FALSE
otherwise. Calling pfMemory::ref, pfMemory::unref,
pfMemory::unrefDelete, pfMemory::unrefGetRef, pfMemory::getRef, or
pfMemory::checkDelete on a Fluxed pfMemory, will actually call the
function on the parent pfFlux.
pfMemory::copy copies src into dst. pfMemory::copy is not recursive - it
does not follow reference chains but instead copies only the first- level
references. The reference counts of objects newly referenced by dst are
incremented by one while those counts of objects previously reverenced by
dst are decremented by one. Objects whose reference counts reach 0 during
pfMemory::copy are not deleted. A value of TRUE will be returned if the
copy successfully completes and FALSE will be returned if an error is
encountered. If the destination object is a growable object (such as a
pfList) then it will automatically grow as needed and as memory permits
to hold the copy of the source object. If the destination object is not
a growable object and the src object is larger than the destination
object, no copy will be done and a value of FALSE will be returned.
pfMemory::copy is currently not implemented for any libpf data structures
and is not implemented for the following libpr data structures:
pfState
pfDataPool
pfMemory::compare compares the object p1 to the object p2. If the
objects are identical, a value of 0 will be returned. Upon the first
difference, a value of (1) will be returned if p1 had a greater value and
a value of (-1) will be returned if p2 had a greater value.
pfMemory::compare is recursive on known defined objects and their sub
objects but is not recursive on user data or generic buffers or lists
that hold undefined data. Derived classes first compare their parent
classes. If objects of different types are compared, they will be found
to be different and the return value will be based on a comparison of the
p1 and p2 pointer values.
Page 7
pfMemory(3pf) OpenGL Performer 3.2.2 libpr C++ Reference Pages pfMemory(3pf)
pfMemory::print Prints information to a file about the specified object.
The file argument specifies the file. The non-static virtual
pfMemory::print takes a prefix string prefix which is prepended to the
message part of the printed statements and which may be NULL to indicate
no prefix. If file is NULL, the listing is printed to stderr.
pfMemory::print takes a verbosity indicator, verbose. Valid selections
in order of increasing verbosity are:
PFPRINT_VB_OFF no printing
PFPRINT_VB_ON minimal printing (default)
PFPRINT_VB_NOTICE minimal printing (default)
PFPRINT_VB_INFO considerable printing
PFPRINT_VB_DEBUG exhaustive printing
If mem is a type of pfNode, then which specifies whether the print
traversal should only traverse the current node (PFTRAV_SELF) or print
out the entire scene graph rooted by node mem by traversing node and its
descendents in the graph (PFTRAV_SELF | PFTRAV_DESCEND). If mem is a
pfFrameStats, then which specifies a bitmask of frame statistics classes
that should be printed. If mem is a pfGeoSet, then which is ignored and
information about that pfGeoSet is printed according to the verbosity
indicator. The output contains the types, names and bounds of the nodes
and pfGeoSets in the hierarchy. This routine is provided for debugging
purposes only and the content and format may change in future releases.
Example 3: Print entire contents of a pfGeoSet, gset, to stderr.
gset->print(NULL, PFPRINT_VB_DEBUG, NULL);
Example 4: Print entire scene graph under node to a file file with
default verbosity.
file = fopen ("scene.out","w");
scene->print(PFTRAV_SELF | PFTRAV_DESCEND, PFPRINT_VB_ON, file);
fclose(file);
Example 5: Print select classes of a pfFrameStats structure, stats, to
stderr.
stats->print(PFSTATS_ENGFX | PFFSTATS_ENDB | PFFSTATS_ENCULL, PFSTATS_ON, NULL);
pfMemory::malloc and the related routines provide a consistent method to
allocate memory, either from the user's heap (using the C-library malloc
function) or from a shared memory arena (using the IRIX amalloc
function). In addition, these routines provide a reference counting
Page 8
pfMemory(3pf) OpenGL Performer 3.2.2 libpr C++ Reference Pages pfMemory(3pf)
mechanism used by OpenGL Performer to efficiently manage memory.
pfMemory::malloc operates identically to the C-library malloc function,
except that a shared memory arena may be specified to allocate the memory
from. If arena is NULL, memory is allocated from the heap, otherwise
memory is allocated from arena which must be a previously configured
shared memory arena (see pfSharedMem). new(nbytes, arena) is equivalent
to pfMemory::malloc(nbytes, arena). new(nbytes) is equivalent to
pfMemory::malloc(nbytes, NULL). "delete ptr" is equivalent to
pfMalloc::free(ptr). Instances of pfMemory and derived classes must be
explicitly new'ed individually, i.e. they cannot be created statically,
on the stack or in arrays.
Shared memory arenas can be created using acreate and can be found by
using pfGetSharedArena.
pfMemory::calloc and pfMemory::realloc function just as their Unix
counterparts, except that they may use shared arenas.
In all cases, a pointer to the allocated memory block is returned or NULL
if there is not enough available memory.
The data pointer returned by pfMemory::malloc, pfMemory::calloc, and
pfMemory::realloc is actually part of a pfMemory object that, among other
things, provides a reference count. Reference counts are used to keep
track of how many times each allocated block of memory is referenced or
instanced. All OpenGL Performer libpr objects (pfMemory) are created
with pfMemory::malloc so their reference counts are updated by
appropriate libpr routines. Examples of references follow:
Example 6:
tex = new pfTexture;
/* Attach 'tex' to gstate0 and gstate1 */
gstate0->setAttr(PFSTATE_TEXTURE, tex);
gstate1->setAttr(PFSTATE_TEXTURE, tex);
/* The reference count of 'tex' is now 2 */
/* Remove 'tex' from gstate1 */
gstate1->setAttr(PFSTATE_TEXTURE, NULL);
/* The reference count of 'tex' is now 1 */
Example 7:
coords = (pfVec3*) pfMalloc(sizeof(pfVec3) * numVerts, arena);
/* Attach 'coords' to non-indexed pfGeoSet, 'gset' */
Page 9
pfMemory(3pf) OpenGL Performer 3.2.2 libpr C++ Reference Pages pfMemory(3pf)
gset->setAttr(PFGS_COORD3, PFGS_PER_VERTEX, coords, NULL);
/* The reference count of 'coords' is now 1 */
Example 8:
/* Attach 'gstate0' to 'gset' */
gset->setGState(gstate0);
/* The reference count of 'gstate0' is now incremented by 1 */
pfMemory::free frees the memory associated with ptr. It is an error to
pfMemory::free memory that was not allocated by pfMemory::malloc,
pfCalloc, or pfMemory::realloc. It is also an error to use any method
other than pfMemory::free or pfBuffer::checkDelete to free memory
allocated by pfMemory::malloc, pfMemory::calloc, or pfMemory::realloc.
pfMemory::free does not honor the reference count of ptr. This means
that you can free a chunk of memory that is still being used (which means
that its reference count is > 0) with potentially disastrous results.
Typical failure modes are in the form of mysterious memory corruption and
segmentation violations.
pfBuffer::checkDelete, however, does honor the reference count of ptr and
will not delete any memory whose reference count is > 0.
pfBuffer::checkDelete returns -1 if ptr is not a pfMalloc pointer, TRUE
if ptr was deleted, and FALSE otherwise. pfBuffer::checkDelete is
recommended if you are not sure of the reference count of a piece of
memory. See the pfObject reference page for more details on
pfBuffer::checkDelete.
pfMemory::getMallocArena returns the arena pointer which ptr was
allocated from or NULL if ptr was allocated from the process heap.
pfMemory::getMallocSize returns the size in bytes of the memory
referenced by ptr or 0 if ptr is not a pfMemory::malloc pointer.
pfMemory::getArenaBytesUsed returns the number of bytes currently
allocated from the shared arena. It takes into account all the Performer
calls that allocate or free shared arena memory (pfMalloc, pfCalloc,
pfRealloc, pfDelete, pfFree, new on any Performer class, etc). This call
is only available in the DEBUG libraries. It is meant for debugging
memory leaks and therefore is not necessary in the optimized libraries.
If called with optimized libraries, it returns (-1). This call makes it
easier to distinguish between memory leaks and memory fragmentation: If
the arena grows but the number of bytes used doesn't then the program in
question causes memory fragmentation but doesn't leak.
Page 10
pfMemory(3pf) OpenGL Performer 3.2.2 libpr C++ Reference Pages pfMemory(3pf)
pfStrdup duplicates the NULL-terminated string str by allocating storage
in the shared memory arena defined by the arena argument.
BUGS
pfMemory::print is not yet implemented for pfGeoStates and other state
structures, and is not implemented for pfPaths or pfLists.
SEE ALSO
acreate, calloc, free, malloc, realloc, pfInitArenas
Page 11