FX::FXMemoryPool Class Reference
[Custom memory allocation infrastructure]

#include <FXMemoryPool.h>

List of all members.


Detailed Description

A threadsafe custom memory pool.

One of the things I've always wanted in my programming library but haven't had since my RISC-OS days is the ability to create arbitrary heaps (called memory pools nowadays as some idiot called a variant of an ordered tree programming pattern a "heap"). RISC-OS made custom heaps very easy as you just called SWI OS_HeapCreate and even today it has the unique property of letting you create one wherever you like. Sadly we couldn't offer this here.

But why would you want to have lots of custom heaps around the place? Because put simply, it can increase performance and reduce memory usage, never mind allowing some isolation of memory corruption and making it easy to prevent memory overuse attacks by malicious parties. Despite the many advantages of using custom heaps, they are very rarely used despite C++ offering per-class allocators. This is a shame, but understandable given you must do slightly more work to make full use of them.

Given there's a lack of documentation on why they're useful, I'll outline it here. Performance increases can be gained especially when allocating lots of small simple objects - you can skip the destruction completely for the entire set by allocating from a custom heap, then simply deleting the heap rather than destroying each individually. Memory usage can be reduced because heaps fragment - the C++ freestore is particularly notorious for this and any algorithm with good performance tends to waste lots of memory in unallocated portions. Thus if you can reduce the fragmentation, you can substantially reduce the working set of your application. Finally, memory corruption can be isolated if you can contain some piece of code to work from a custom heap - if it dies horribly, you can be pretty safe with some kinds of code to delete the heap and be sure the corruption won't spread - like cutting out a cancer. Don't over-rely on this however.

As of v0.80 of TnFOX, FXMemoryPool has been substantially augmented from the merging of TMemPool into it from Tn. Furthermore there is now process-wide replacement of all dynamic memory allocation to use this library instead. The default STDC malloc, calloc, realloc and free have been left available as sometimes a third party library will return a pointer to you which you must later free and using the TnFOX replacements will cause a segfault. There is now a facility for a "current pool" set per thread which causes all global memory allocations to occur from that pool. See FX::FXMemPoolHold.

This particular heap implementation is not my own - previous to v0.86 it used the famous ptmalloc2 which is the standard allocator in GNU glibc (and thus is the standard allocator for Linux). As of v0.86 onwards it uses nedmalloc, an even better memory allocator once again. nedmalloc has a similar design to ptmalloc2 except that it adds a threadcache for improved scalability so the following resources remain useful:

ptmalloc2 was shown to have the optimum speed versus wastefulness of all thread-optimised allocators according to Sun (http://developers.sun.com/solaris/articles/multiproc/multiproc.html). You can read more about how ptmalloc2's algorithm works at http://gee.cs.oswego.edu/dl/html/malloc.html. Note that nedmalloc is compiled in debug mode when TnFOX is compiled as such - thus you may get assertion errors if you corrupt the nedmalloc based heap.

If you'd like to know more in general about heap algorithms, implementations and performance, please see ftp://ftp.cs.utexas.edu/pub/garbage/allocsrv.ps

Note:
In debug modes, by default the system allocator is used exclusively with extensive additional sanity checks. Please consult the custom memory infrastructure page for more information.

Usage:

You are guaranteed that irrespective of which memory pool you allocate from, you can free it with any other memory pool in effect. This is a requirement for any serious usage. When you create a FXMemoryPool, you can supply which thread you wish to associate it with - when that thread exits, the memory pool will automatically be deleted. Deletion of a memory pool can take one of two forms - either immediate, or marked for deletion when the last block allocated within it is freed.

FXMemoryPool keeps some statistics of how many memory pools are in use and how much data has been allocated in each. This can be monitored during testing to ensure that you haven't forgotten to use a memory pool when you should.

TnFOX defines implementations of the ANSI C dynamic memory functions within the FX namespace but it also defines templated versions for easier type casting plus all versions take an optional parameter allowing you to manually specify which heap to use. The global new and delete operator overrides similarly have such an extra (optional) parameter.

Public Member Functions

 FXMemoryPool (FXuval maximum=(FXuval)-1, const char *identifier=0, QThread *owner=0, bool lazydeleted=false)
FXuval size () const throw ()
FXuval maxsize () const throw ()
FXMALLOCATTR void * malloc (FXuval size) throw ()
FXMALLOCATTR void * calloc (FXuint no, FXuval size) throw ()
void free (void *blk) throw ()
FXMALLOCATTR void * realloc (void *blk, FXuval size) throw ()

Static Public Member Functions

static FXMemoryPoolpoolFromBlk (void *blk) throw ()
static FXMALLOCATTR void * glmalloc (FXuval size) throw ()
static FXMALLOCATTR void * glcalloc (FXuval no, FXuval size) throw ()
static void glfree (void *blk) throw ()
static FXMALLOCATTR void * glrealloc (void *blk, FXuval size) throw ()
static bool gltrim (FXuval left) throw ()
static Statistics glstats () throw ()
static FXString glstatsAsString ()
static FXMemoryPoolcurrent ()
static void setCurrent (FXMemoryPool *heap)
static QMemArray< MemoryPoolInfostatistics ()

Static Public Attributes

static const FXuval minHeapVirtualSpace

Friends

FXAPI void * malloc (size_t size, FXMemoryPool *heap) throw ()
FXAPI void * calloc (size_t no, size_t _size, FXMemoryPool *heap) throw ()
FXAPI void * realloc (void *p, size_t size, FXMemoryPool *heap) throw ()
FXAPI void free (void *p, FXMemoryPool *heap) throw ()

Classes

struct  MemoryPoolInfo
 Data reflecting a memory pool. More...
struct  Statistics
 A structure containing statistics about the pool. More...


Constructor & Destructor Documentation

FX::FXMemoryPool::FXMemoryPool ( FXuval  maximum = (FXuval)-1,
const char *  identifier = 0,
QThread owner = 0,
bool  lazydeleted = false 
)

Allocates a pool which can grow to size maximum. Virtual address space is allocated in blocks of FX::FXMemoryPool::minHeapVirtualSpace so you might as well allocate one of those by default. You can also set an identifier (for debugging) and associate the pool with a thread whereby when that thread exits, the pool will be deleted. Setting lazydeleted means the pool doesn't really die after destruction until the last block is freed from it.


Member Function Documentation

FXuval FX::FXMemoryPool::size (  )  const throw ()

Returns the size of the pool.

FXuval FX::FXMemoryPool::maxsize (  )  const throw ()

Returns the maximum size of the pool.

FXMALLOCATTR void* FX::FXMemoryPool::malloc ( FXuval  size  )  throw ()

Allocates a block, returning zero if unable.

FXMALLOCATTR void* FX::FXMemoryPool::calloc ( FXuint  no,
FXuval  size 
) throw ()

Allocates a zero initialised block, returning zero if unable.

void FX::FXMemoryPool::free ( void *  blk  )  throw ()

Frees a block.

FXMALLOCATTR void* FX::FXMemoryPool::realloc ( void *  blk,
FXuval  size 
) throw ()

Extends a block, returning zero if unable. Note that like the ANSI realloc() you must still free blk on failure.

static FXMemoryPool* FX::FXMemoryPool::poolFromBlk ( void *  blk  )  throw () [static]

Returns the memory pool associated with a memory chunk (=0 if from system pool, =-1 if not from any pool).

static FXMALLOCATTR void* FX::FXMemoryPool::glmalloc ( FXuval  size  )  throw () [static]

Allocates a block from the global heap, returning zero if unable.

static FXMALLOCATTR void* FX::FXMemoryPool::glcalloc ( FXuval  no,
FXuval  size 
) throw () [static]

Allocates zero-filled no of blocks of size size from the global heap, returning zero if unable

static void FX::FXMemoryPool::glfree ( void *  blk  )  throw () [static]

Frees a block from the global heap.

static FXMALLOCATTR void* FX::FXMemoryPool::glrealloc ( void *  blk,
FXuval  size 
) throw () [static]

Extends a block in the global heap, returning zero if unable. Note that like the ANSI realloc() you must still free blk on failure.

static bool FX::FXMemoryPool::gltrim ( FXuval  left  )  throw () [static]

Trims the heap down to the minimum possible, releasing memory back to the system.

static Statistics FX::FXMemoryPool::glstats (  )  throw () [static]

Returns a set of usage statistics about the heap.

static FXString FX::FXMemoryPool::glstatsAsString (  )  [static]

Returns a set of usage statistics about the heap as a string.

static FXMemoryPool* FX::FXMemoryPool::current (  )  [static]

Retrieves the memory pool in use by the current thread (=0 for system pool).

static void FX::FXMemoryPool::setCurrent ( FXMemoryPool heap  )  [static]

Sets the memory pool to be used by the current thread (=0 for system pool).

static QMemArray<MemoryPoolInfo> FX::FXMemoryPool::statistics (  )  [static]

Returns a list of memory pools existing.


Friends And Related Function Documentation

FXAPI void* malloc ( size_t  size,
FXMemoryPool heap 
) throw () [friend]

Allocates memory

Allocates memory

FXAPI void* calloc ( size_t  no,
size_t  _size,
FXMemoryPool heap 
) throw () [friend]

Allocates memory

Allocates memory

FXAPI void* realloc ( void *  p,
size_t  size,
FXMemoryPool heap 
) throw () [friend]

Resizes memory

FXAPI void free ( void *  p,
FXMemoryPool heap 
) throw () [friend]

Frees memory


Member Data Documentation

Defines the size of block virtual address space is allocated in.


The documentation for this class was generated from the following file:

(C) 2002-2008 Niall Douglas. Some parts (C) to assorted authors.
Generated on Fri Jun 13 22:05:32 2008 for TnFOX by doxygen v1.5.6