Custom memory allocation infrastructure


Detailed Description

Tn for security reasons requires a substantially more enhanced dynamic memory allocation system - in particular, threads performing operations by remote instruction must ensure that resource depletion attacks are prevented. This is done by running a separate memory pool per remote client which can either be chosen explicitly or via a TLS variable.

Concurrent with this is the need to replace the system allocator on Win32 with TnFOX's one which typically yields a 6x speed increase for multithreaded C++ programs. A unified system is required for all this as there is only one global new and delete operator. It is rather important that you read and understand the following discussion.

Due to how C++ (and C) works, there is one global new and delete operator which supposedly can be wholly replaced by any program according to the standard. This isn't actually true - on Win32, you can only replace per binary (DLL or EXE) and on GNU/ELF/POSIX your operator replacements get happily overrided by any shared objects loaded after your binary. It gets worse - when working with containers or any code which speculatively allocates memory (eg; buffering), a container can quickly come to consist of blocks allocated from a multitude of memory pools all at once leaving us with no choice other than to permit any thread with any memory pool currently set to be able to free any other allocation, no matter where it was allocated. Furthermore, we must also tolerate other parts of the C library or STL allocating with the default allocator and freeing using ours (GCC is particularly bad for this when optimisation is turned on).

It was for all these reasons that getting the custom memory allocation infrastructure working took a week or so of testing. I tried a number of schemes and eventually came down with one which is reasonably fast but does cost an extra four bytes per allocation within a non-global memory pool. You the user must also observe some caveats:

  1. Do not combine TnFOX with any code which also replaces the global new and delete operators where those operators do not use directly malloc() and free(). Both MSVC and GCC are fine here.
  2. Do not mix direct use of a FX::FXMemoryPool via its methods with passing it as a parameter to any of the global allocation functions. If you do you will get a segfault.
  3. By using TnFOX, you imply you will not define your own global new and delete operators. If you try, you will get a compile error as an inlined version is defined anywhere a TnFOX header file is included.
That inlined version just mentioned is done to ensure all TnFOX code is permanently bound to the TnFOX allocator. It cannot be overriden subsequently. It furthermore doesn't bother calling a new handler as set by std::set_new_handler().

There are some defines which affect how the custom memory allocation system works:


Classes

class  FX::FXMemoryPool
 A threadsafe custom memory pool. More...

Functions

template<typename T>
FXMALLOCATTR T * FX::malloc (size_t size, FXMemoryPool *heap=0) throw ()
template<typename T>
FXMALLOCATTR T * FX::calloc (size_t no, size_t size, FXMemoryPool *heap=0) throw ()
template<typename T>
FXMALLOCATTR T * FX::realloc (T *p, size_t size, FXMemoryPool *heap=0) throw ()
template<typename T>
void FX::free (T *p, FXMemoryPool *heap=0) throw ()
FXMALLOCATTR char * FX::strdup (const char *str) throw ()
FXDLLPUBLIC FXMALLOCATTR void * operator new (size_t size) throw (std::bad_alloc)
FXDLLPUBLIC FXMALLOCATTR void * operator new[] (size_t size) throw (std::bad_alloc)
FXDLLPUBLIC void operator delete (void *p) throw ()
FXDLLPUBLIC void operator delete[] (void *p) throw ()
FXDLLPUBLIC FXMALLOCATTR void * operator new (size_t size, FX::FXMemoryPool *heap) throw (std::bad_alloc)
FXDLLPUBLIC FXMALLOCATTR void * operator new[] (size_t size, FX::FXMemoryPool *heap) throw (std::bad_alloc)
FXDLLPUBLIC void operator delete (void *p, FX::FXMemoryPool *heap) throw ()
FXDLLPUBLIC void operator delete[] (void *p, FX::FXMemoryPool *heap) throw ()
FXAPI FXMALLOCATTR void * FX::realloc (void *p, size_t size, FXMemoryPool *heap=0) throw ()
FXAPI void FX::free (void *p, FXMemoryPool *heap=0) throw ()
FXAPI void FX::failonfree (void *p, FXMemoryPool *heap=0) throw ()
FXAPI void FX::unfailonfree (void *p, FXMemoryPool *heap=0) throw ()
FXAPI FXMALLOCATTR void * tnfxmalloc (size_t size)
FXAPI FXMALLOCATTR void * tnfxcalloc (size_t no, size_t size)
FXAPI FXMALLOCATTR void * tnfxrealloc (void *p, size_t size)
FXAPI void tnfxfree (void *p)


Function Documentation

template<typename T>
FXAPI FXMALLOCATTR void * FX::malloc ( size_t  size,
FXMemoryPool *  heap = 0 
) throw () [inline]

Allocates memory

Allocates memory

References FX::Secure::malloc().

template<typename T>
FXAPI FXMALLOCATTR void * FX::calloc ( size_t  no,
size_t  size,
FXMemoryPool *  heap = 0 
) throw () [inline]

Allocates memory

Allocates memory

References FX::Secure::calloc().

template<typename T>
T * FX::realloc ( T *  p,
size_t  size,
FXMemoryPool *  heap = 0 
) throw () [inline]

Resizes memory

References FX::realloc().

template<typename T>
void FX::free ( T *  p,
FXMemoryPool *  heap = 0 
) throw () [inline]

Frees memory

References FX::Secure::free().

char * FX::strdup ( const char *  str  )  throw () [inline]

Duplicates a string

References FX::Secure::malloc().

FXDLLPUBLIC void * operator new ( size_t  size  )  throw (std::bad_alloc) [inline]

Global operator new replacement

References FX::Secure::malloc().

FXDLLPUBLIC void * operator new[] ( size_t  size  )  throw (std::bad_alloc) [inline]

Global operator new replacement

References FX::Secure::malloc().

FXDLLPUBLIC void operator delete ( void *  p  )  throw () [inline]

Global operator delete replacement

References FX::Secure::free().

FXDLLPUBLIC void operator delete[] ( void *  p  )  throw () [inline]

Global operator delete replacement

References FX::Secure::free().

FXDLLPUBLIC void * operator new ( size_t  size,
FX::FXMemoryPool heap 
) throw (std::bad_alloc) [inline]

operator new with a specific pool

References FX::Secure::malloc().

FXDLLPUBLIC void * operator new[] ( size_t  size,
FX::FXMemoryPool heap 
) throw (std::bad_alloc) [inline]

operator new with a specific pool

References FX::Secure::malloc().

FXDLLPUBLIC void operator delete ( void *  p,
FX::FXMemoryPool heap 
) throw () [inline]

operator delete with a specific pool

References FX::Secure::free().

FXDLLPUBLIC void operator delete[] ( void *  p,
FX::FXMemoryPool heap 
) throw () [inline]

operator delete with a specific pool

References FX::Secure::free().

FXAPI FXMALLOCATTR void* FX::realloc ( void *  p,
size_t  size,
FXMemoryPool *  heap = 0 
) throw ()

Resizes memory

Referenced by FX::realloc().

FXAPI void FX::free ( void *  p,
FXMemoryPool *  heap = 0 
) throw ()

Frees memory

FXAPI void FX::failonfree ( void *  p,
FXMemoryPool *  heap = 0 
) throw ()

Causes an assertion failure when the specified memory block is freed

FXAPI void FX::unfailonfree ( void *  p,
FXMemoryPool *  heap = 0 
) throw ()

Removes a previous FX::failonfree()

FXAPI FXMALLOCATTR void* tnfxmalloc ( size_t  size  ) 

Allocates memory

FXAPI FXMALLOCATTR void* tnfxcalloc ( size_t  no,
size_t  size 
)

Allocates memory

FXAPI FXMALLOCATTR void* tnfxrealloc ( void *  p,
size_t  size 
)

Resizes memory

FXAPI void tnfxfree ( void *  p  ) 

Frees memory


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