/* ----------------------------------------------------------------------------- GSFramework Copyright 2001-2013 Emmanuel Julien. All Rights Reserved. ----------------------------------------------------------------------------- */ #ifndef __NALLOCATOR_INTERFACE__ #define __NALLOCATOR_INTERFACE__ #include "ntypes.h" #include namespace GS { namespace Alloc { // Allocator systems. enum System { General, ListItem, StringBuffer, Filesystem, Metatag, Curve, Motion, AnimationSource, Vector, Matrix, Physics, Item3d, Geometry, Material, Texture, Picture, Mixer, Sound, Renderer, RendererJob, RendererTerrain, VertexBuffer, Global, SystemCount }; struct SystemDesc { const char *group; const char *name; }; /* Allocators can be changed per system by editing the following defines. */ #define MemAllocListItem GS::Alloc::DefaultAllocator #define MemAllocStringBuffer GS::Alloc::DefaultAllocator #define MemAllocFilesystem GS::Alloc::DefaultAllocator #define MemAllocMetatag GS::Alloc::DefaultAllocator #define MemAllocCurve GS::Alloc::DefaultAllocator #define MemAllocMotion GS::Alloc::DefaultAllocator #define MemAllocAnimationSource GS::Alloc::DefaultAllocator #define MemAllocVector GS::Alloc::DefaultAllocator #define MemAllocMatrix GS::Alloc::DefaultAllocator #define MemAllocPhysics GS::Alloc::DefaultAllocator #define MemAllocItem3d GS::Alloc::DefaultAllocator #define MemAllocGeometry GS::Alloc::DefaultAllocator #define MemAllocMaterial GS::Alloc::DefaultAllocator #define MemAllocTexture GS::Alloc::DefaultAllocator #define MemAllocPicture GS::Alloc::DefaultAllocator #define MemAllocMixer GS::Alloc::DefaultAllocator #define MemAllocSound GS::Alloc::DefaultAllocator #define MemAllocRenderer GS::Alloc::DefaultAllocator #define MemAllocRendererJob GS::Alloc::DefaultAllocator #define MemAllocRendererTerrain GS::Alloc::DefaultAllocator #define MemAllocVertexBuffer GS::Alloc::DefaultAllocator #if __ENABLE_ALLOCATION_STAT__ struct Header { size_t size; }; struct Stat { uint alloc_count, alloc_avg; uint alive_count, alive_count_peak; size_t size, size_peak; Stat() : alloc_count(0), alloc_avg(0), alive_count(0), alive_count_peak(0), size(0), size_peak(0) {} }; /// Per system statistics. extern Stat system_stat[SystemCount]; extern SystemDesc system_desc[SystemCount]; size_t GetAdjustedAllocationSize(size_t); void *SetupAllocationStat(void *, size_t); void *GetAllocationStat(void *, Header *&); void UpdateStatAlloc(size_t, System); void UpdateStatDelete(size_t, System); #endif /// Standard C++ allocator. struct DefaultAllocator { static void *Alloc(size_t size, System sys = General); static void Delete(void *addr, System sys = General); }; } // Alloc } // GS //------------------------------------------------------------------------------ #if __ENABLE_ALLOCATION_STAT__ #define __NSTAT_WRAPALLOC(__WRAPPED_CALL, __SYSTEM)\ GS::Alloc::UpdateStatAlloc(size, __SYSTEM);\ size_t __raw_size = size;\ size = GS::Alloc::GetAdjustedAllocationSize(size);\ return GS::Alloc::SetupAllocationStat(__WRAPPED_CALL, __raw_size); #define __NSTAT_WRAPDELETE(__WRAPPED_CALL, __SYSTEM)\ if (addr)\ {\ GS::Alloc::Header *h;\ addr = GS::Alloc::GetAllocationStat(addr, h);\ GS::Alloc::UpdateStatDelete(h->size, __SYSTEM);\ __WRAPPED_CALL;\ } #define __NSTAT_ALLOC(__SIZE, __SYSTEM) GS::Alloc::UpdateStatAlloc(__SIZE, __SYSTEM) #define __NSTAT_DELETE(__SIZE, __SYSTEM) GS::Alloc::UpdateStatDelete(__SIZE, __SYSTEM) #else #define __NSTAT_WRAPALLOC(__WRAPPED_CALL, __SYSTEM) return __WRAPPED_CALL; #define __NSTAT_WRAPDELETE(__WRAPPED_CALL, __SYSTEM) __WRAPPED_CALL; #define __NSTAT_ALLOC(__SIZE, __SYSTEM) #define __NSTAT_DELETE(__SIZE, __SYSTEM) #endif //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ #if __PLATFORM_EMSCRIPTEN__ #define NPLACEMENT_NEW(__SYSTEM) #else #define NPLACEMENT_NEW(__SYSTEM)\ void *operator new (size_t size)\ { return MemAlloc##__SYSTEM::Alloc(size, GS::Alloc::__SYSTEM); }\ void operator delete(void *addr)\ { MemAlloc##__SYSTEM::Delete(addr, GS::Alloc::__SYSTEM); }\ void *operator new [] (size_t size)\ { return MemAlloc##__SYSTEM::Alloc(size, GS::Alloc::__SYSTEM); }\ void operator delete [] (void *addr)\ { MemAlloc##__SYSTEM::Delete(addr, GS::Alloc::__SYSTEM); } #endif //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void *_align_alloc(size_t, size_t); void _align_free(void *); template T *_align_new(size_t align) { return ::new (_align_alloc(sizeof(T), align)) T(); } template T *_align_new(P0 &p0, size_t align) { return ::new (_align_alloc(sizeof(T), align)) T(p0); } template void _align_delete(T *p) { p->~T(); _align_free(p); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ template void _safe_delete(T *&p) { delete p; p = 0; } template void _safe_delete_array(T *&p) { delete [] p; p = 0; } //------------------------------------------------------------------------------ #endif // __NALLOCATOR_INTERFACE__