Memory Management: 3.8 Using Global Memory: The Reference Count

Up: GEOS SDK TechDocs | Up | Prev: 3.7 Retrieving Block Information | Next: 4 malloc()
MemInitRefCount(), MemIncRefCount(), MemDecRefCount()

Sometimes several different threads will need to look at the same block of memory. For example, a single thread might need to send the same information to objects in several different threads. The simplest way to do that would be to write the information in a global memory block and pass the block's handle to the objects. However, it's a bad idea to allocate global blocks for longer than necessary, since this uses up handles. It therefore becomes important to free these blocks when everyone's done with them.

GEOS provides a simple mechanism for managing this. Every block can have a reference count . When a reference count for a block reaches zero, the block is automatically freed. That way, for example, if an object needed to send the same information to five objects, it could write the data to a block, give that data block a reference count of five, and send the block's handle to the objects. Each object, when it finished accessing the data, would decrement the data block's reference count. When all five objects had decremented the reference count, the block would be freed.

You must be careful about a few things while using the reference count mechanism. First of all, the reference count is kept in the HM _otherInfo field of the block's handle table entry. For this reason, you must not use the reference count routines if you will be using HM _otherInfo for any other purpose. In particular:

Once the reference count is decremented to zero, the block is immediately freed. Once a block is freed, its handle may be used for something else. If you try to increment or decrement the reference count of the block, the results are undefined. For this reason, you should make sure that the reference count does not reach zero until all threads are done with the block. One way to arrange for this is to have a single thread do all the decrementing. For example, an object might set the reference count to five, and send the handle to five other objects. Each of these objects, when finished with the block, would send a message back to the first object, which would decrement the reference count. As an alternative, you could have each of the objects decrement the count itself when it was finished. In this case, the first object would have to assume that the block was freed as soon as it sent out all of the messages, since it would have no way of knowing when the other objects would be finished with the block.

Finally, since the reference count is stored in HM _otherInfo , it has a maximum value of (216-1). If you try to increment the reference count past this value, the results are undefined. This will not be a problem for most applications.

To set up a reference count for a block, call MemInitRefCount() . This routine takes two arguments: the handle of a global memory block, and the reference count for that block. The reference count must be greater than zero. MemInitRefCount() sets the block's HM _otherInfo field to the specified reference count. MemInitRefCount() does not return anything.

To increment the reference count, call MemIncRefCount() . This routine is passed a single argument, namely the handle of the global memory block. The routine simply increments HM _otherInfo . It does not return anything.

To decrement the reference count, call MemDecRefCount() . This routine is passed the handle of a global memory block. It decrements the block's HM _otherInfo field. If the field reaches zero, MemDecRefCount() will immediately free the block. The routine does not return anything.


Up: GEOS SDK TechDocs | Up | Prev: 3.7 Retrieving Block Information | Next: 4 malloc()