/* ZAlloc.hpp (created 9/12/10) Author : James Russell Purpose : Memory allocation library and memory allocation tracker for ZEngine. If ZALLOC_EXTRA_SPAMMY is defined, then allocations will log a message to stderr when allocation occurs indicating how much. License: TODO */ #pragma once #ifndef _ZALLOC_H #define _ZALLOC_H #include #include //The compiler really should be smart enough to include size_t in the global //namespace by default. But, on some Linux configurations, it will drop //it in std. Explicitly including this doesn't hurt anything. #include #if ZALLOC_CHECK_ALLOC //Memory Checkpoint Struct struct ZMemState { int Checkpoint; //Checkpoint Number }; //Allocation Info Struct struct ZAllocInfo { static int CurrentAllocCount; //Current number of unfreed allocations static int CurrentCheckpoint; //Static current checkpoint tracker ZAllocInfo* Next; //Next Info Node uintptr_t Address; //Address assigned size_t Size; //Size of the allocation int Line; //Line Number int Checkpoint; //Checkpoint Integer char File[128]; //File String }; //Adds a tracking node for an allocation extern void ZAllocAddTrack(uintptr_t _address, size_t _size, const char *_file, int _line, int _checkpoint); //Removes a tracking node for an allocation extern void ZAllocRemoveTrack(uintptr_t _address); //Dumps unfreed memory string containing a list of memory leaks extern void ZAllocDumpUnfreed(ZMemState *_state); //Debug Placement Operator New extern void* operator new(size_t _size, const char *_file, int _line, int _checkpoint) throw(); extern void* operator new[](size_t _size, const char *_file, int _line, int _checkpoint) throw(); //Debug Placement Delete extern void operator delete(void *_ptr, const char* _file, int _line, int _checkpoint); extern void operator delete[](void *_ptr, const char* _file, int _line, int _checkpoint); //Our arguments to znew #define ZNEW_ARGS (__FILE__, __LINE__, ZAllocInfo::CurrentCheckpoint) //Macros for declaring a memory 'checkpoint' and //dumping memory leaks to stderr #define ZALLOC_MEM_CHECKPOINT(stateP) stateP->Checkpoint = AtomicAddReturn((volatile int*)&ZAllocInfo::CurrentCheckpoint, 1) #define ZALLOC_MEM_DUMP_LEAKS(stateP) ZAllocDumpUnfreed(stateP) #else //!ZALLOC_CHECK_ALLOC #define ZNEW_ARGS (std::nothrow) #define ZALLOC_MEM_CHECKPOINT(stateP) #define ZALLOC_MEM_DUMP_LEAKS(stateP) #endif //ZALLOC_CHECK_ALLOC /* Some definitions we need for znew_static */ //This is used to indicate a static allocation (basically a type flag) struct znew_static_t { }; //Our actual static allocation overrides extern void* operator new(size_t _size, znew_static_t _staticAlloc); extern void* operator new[](size_t _size, znew_static_t _staticAlloc); /* Some Memory Management Macros */ //znew loves you! #define znew new ZNEW_ARGS //Allocate with params #define znew_notrack new (std::nothrow) //Allocate without tracking #define znew_static new (znew_static_t()) //Allocate, but register for delete onexit #define zdelete delete //Delete #define zalloc(_type, _size) ZAlloc::Alloc<_type>(_size) //Allocates an array (block of memory) using the ZAlloc allocation library #define zfree(_data) ZAlloc::Free(_data) //Frees an array (block of memory) using the ZAlloc allocation library #define MemCopy(_type, _dest, _src, _count) memcpy(_dest, _src, _count * sizeof(_type)) #define MemCopyFloat(_dest, _src, _count) memcpy(_dest, _src, _count * sizeof(float)) #define MemCopyInt(_dest, _src, _count) memcpy(_dest, _src, _count * sizeof(int)) #define MemCopyChar(_dest, _src, _count) memcpy(_dest, _src, _count * sizeof(char)) #define MemMove(_type, _dest, _src, _count) memmove(_dest, _src, _count * sizeof(_type)) #define MemMoveFloat(_dest, _src, _count) memmove(_dest, _src, _count * sizeof(float)) #define MemMoveInt(_dest, _src, _count) memmove(_dest, _src, _count * sizeof(int)) #define MemMoveChar(_dest, _src, _count) memmove(_dest, _src, _count * sizeof(char)) #define MemSet(_type, _dest, _val, _count) memset(_dest, _val, _count * sizeof(_type)) #define MemSetFloat(_dest, _val, _count) memset(_dest, _val, _count * sizeof(float)) #define MemSetInt(_dest, _val, _count) memset(_dest, _val, _count * sizeof(int)) #define MemSetChar(_dest, _val, _count) memset(_dest, _val, _count * sizeof(char)) class ZAlloc { public: /* static public Alloc Allocation function. Gives back an allocated array of at least _size in length. @param _size - the size of the block of type T @return (T*) - an array of T of at least _size in length */ template static T* Alloc(size_t _size); /* public static Free Free function. @param _data - an array allocated through the use of Alloc @return (void) */ template static void Free(T *_data); }; template T* ZAlloc::Alloc(size_t _size) { return new (std::nothrow) T[_size]; } template void ZAlloc::Free(T *_data) { delete [] _data; } #endif