00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #if !defined(FXDEFS_H) && !defined(DOXYGEN_SHOULD_SKIP_THIS)
00023 #include "fxdefs.h"
00024 #else
00025
00026 #ifndef FXMEMORYPOOL_H
00027 #define FXMEMORYPOOL_H
00028
00033 #ifdef _MSC_VER
00034
00035 #pragma warning(disable: 4290) // C++ exception specification ignored except it's not nothrow
00036 #endif
00037
00038 #include <string.h>
00039 #include <new>
00040
00041
00069 namespace FX {
00070
00071 class FXMemoryPool;
00072 class QThread;
00073
00076 extern FXAPI FXMALLOCATTR void *malloc(size_t size, FXMemoryPool *heap=0, FXuint alignment=0) throw();
00079 extern FXAPI FXMALLOCATTR void *calloc(size_t no, size_t size, FXMemoryPool *heap=0, FXuint alignment=0) throw();
00082 extern FXAPI FXMALLOCATTR void *realloc(void *p, size_t size, FXMemoryPool *heap=0) throw();
00085 extern FXAPI void free(void *p, FXMemoryPool *heap=0) throw();
00086
00089 template<typename T> inline FXMALLOCATTR T *malloc(size_t size, FXMemoryPool *heap=0, FXuint alignment=0) throw();
00090 template<typename T> inline T *malloc(size_t size, FXMemoryPool *heap, FXuint alignment) throw() { return (T *) FX::malloc(size, heap, alignment); }
00093 template<typename T> inline FXMALLOCATTR T *calloc(size_t no, size_t size, FXMemoryPool *heap=0, FXuint alignment=0) throw();
00094 template<typename T> inline T *calloc(size_t no, size_t size, FXMemoryPool *heap, FXuint alignment) throw() { return (T *) FX::calloc(no, size, heap, alignment); }
00097 template<typename T> inline FXMALLOCATTR T *realloc(T *p, size_t size, FXMemoryPool *heap=0) throw();
00098 template<typename T> inline T *realloc(T *p, size_t size, FXMemoryPool *heap) throw() { return (T *) FX::realloc((void *) p, size, heap); }
00101 template<typename T> inline void free(T *p, FXMemoryPool *heap=0) throw() { FX::free((void *) p, heap); }
00102 #if defined(DEBUG)
00103 extern FXAPI FXMALLOCATTR void *malloc_dbg(const char *file, const char *function, int lineno, size_t size, FXMemoryPool *heap=0, FXuint alignment=0) throw();
00104 extern FXAPI FXMALLOCATTR void *calloc_dbg(const char *file, const char *function, int lineno, size_t no, size_t size, FXMemoryPool *heap=0, FXuint alignment=0) throw();
00105 extern FXAPI FXMALLOCATTR void *realloc_dbg(const char *file, const char *function, int lineno, void *p, size_t size, FXMemoryPool *heap=0) throw();
00106
00107 template<typename T> inline FXMALLOCATTR T *malloc_dbg(const char *file, const char *function, int lineno, size_t size, FXMemoryPool *heap=0, FXuint alignment=0) throw();
00108 template<typename T> inline T *malloc_dbg(const char *file, const char *function, int lineno, size_t size, FXMemoryPool *heap, FXuint alignment) throw() { return (T *) malloc_dbg(file, function, lineno, size, heap, alignment); };
00109 template<typename T> inline FXMALLOCATTR void *calloc_dbg(const char *file, const char *function, int lineno, size_t no, size_t size, FXMemoryPool *heap=0, FXuint alignment=0) throw();
00110 template<typename T> inline T *calloc_dbg(const char *file, const char *function, int lineno, size_t no, size_t size, FXMemoryPool *heap, FXuint alignment) throw() { return (T *) calloc_dbg(file, function, lineno, no, size, heap, alignment); };
00111 template<typename T> inline FXMALLOCATTR T *realloc_dbg(const char *file, const char *function, int lineno, T *ptr, size_t size, FXMemoryPool *heap=0) throw();
00112 template<typename T> inline T *realloc_dbg(const char *file, const char *function, int lineno, T *ptr, size_t size, FXMemoryPool *heap) throw() { return (T *) realloc_dbg(file, function, lineno, (void *) ptr, size, heap); };
00113 }
00114
00115 inline FXMALLOCATTR void *malloc_dbg(const char *file, const char *function, int lineno, size_t size) throw() { return malloc(size); }
00116 inline FXMALLOCATTR void *calloc_dbg(const char *file, const char *function, int lineno, size_t no, size_t size) throw() { return calloc(no, size); }
00117 inline FXMALLOCATTR void *realloc_dbg(const char *file, const char *function, int lineno, void *ptr, size_t size) throw() { return realloc(ptr, size); }
00118 namespace FX {
00119 extern FXAPI bool printLeakedBlocks() throw();
00120 #endif
00121
00124 inline FXMALLOCATTR char *strdup(const char *str) throw();
00125 inline char *strdup(const char *str) throw()
00126 {
00127 size_t len=strlen(str);
00128 void *ret=FX::malloc(len+1);
00129 if(!ret) return NULL;
00130 memcpy(ret, str, len+1);
00131 return (char *) ret;
00132 }
00135 extern FXAPI void failonfree(void *p, FXMemoryPool *heap=0) throw();
00138 extern FXAPI void unfailonfree(void *p, FXMemoryPool *heap=0) throw();
00139
00147 template<typename T, int alignment> class aligned_allocator
00148 {
00149 public:
00150 typedef T *pointer;
00151 typedef const T *const_pointer;
00152 typedef T &reference;
00153 typedef const T &const_reference;
00154 typedef T value_type;
00155 typedef size_t size_type;
00156 typedef ptrdiff_t difference_type;
00157 T *address(T &r) const { return &r; }
00158 const T *address(const T &s) const { return &s; }
00159 size_t max_size() const { return (static_cast<size_t>(0) - static_cast<size_t>(1)) / sizeof(T); }
00160 template <typename U> struct rebind {
00161 typedef aligned_allocator<U, alignment> other;
00162 };
00163 bool operator!=(const aligned_allocator &other) const { return !(*this == other); }
00164 bool operator==(const aligned_allocator &other) const { return true; }
00165
00166 void construct(T *const p, const T &t) const {
00167 void * const pv = static_cast<void *>(p);
00168 new (pv) T(t);
00169 }
00170 void destroy(T *const p) const {
00171 p->~T();
00172 }
00173 aligned_allocator() { }
00174 aligned_allocator(const aligned_allocator &) { }
00175 template <typename U> aligned_allocator(const aligned_allocator<U, alignment> &) { }
00176
00177 T *allocate(const size_t n) const {
00178 void *pv = malloc(n * sizeof(T), 0, alignment);
00179 if (pv == NULL) throw std::bad_alloc();
00180 return static_cast<T *>(pv);
00181 }
00182 void deallocate(T *p, const size_t n) const {
00183 free(p, 0);
00184 }
00185 template <typename U> T * allocate(const size_t n, const U * ) const {
00186 return allocate(n);
00187 }
00188 private:
00189 aligned_allocator &operator=(const aligned_allocator &);
00190 };
00191
00192
00193 }
00194
00197 inline FXDLLPUBLIC FXMALLOCATTR void *operator new(size_t size, FX::FXMemoryPool *heap, FX::FXuint alignment=0) throw(std::bad_alloc);
00198 inline FXDLLPUBLIC void *operator new(size_t size, FX::FXMemoryPool *heap, FX::FXuint alignment) throw(std::bad_alloc)
00199 {
00200 void *ret;
00201 if(!(ret=FX::malloc(size, heap, alignment))) throw std::bad_alloc();
00202 return ret;
00203 }
00206 inline FXDLLPUBLIC FXMALLOCATTR void *operator new[](size_t size, FX::FXMemoryPool *heap, FX::FXuint alignment=0) throw(std::bad_alloc);
00207 inline FXDLLPUBLIC void *operator new[](size_t size, FX::FXMemoryPool *heap, FX::FXuint alignment) throw(std::bad_alloc)
00208 {
00209 void *ret;
00210 if(!(ret=FX::malloc(size, heap, alignment))) throw std::bad_alloc();
00211 return ret;
00212 }
00215 inline FXDLLPUBLIC void operator delete(void *p, FX::FXMemoryPool *heap) throw()
00216 {
00217 if(p) FX::free(p, heap);
00218 }
00221 inline FXDLLPUBLIC void operator delete[](void *p, FX::FXMemoryPool *heap) throw()
00222 {
00223 if(p) FX::free(p, heap);
00224 }
00225 #ifdef DEBUG
00226 inline FXDLLPUBLIC FXMALLOCATTR void *operator new(size_t size, const char *file, const char *function, int lineno, FX::FXMemoryPool *heap, FX::FXuint alignment) throw(std::bad_alloc);
00227 inline FXDLLPUBLIC void *operator new(size_t size, const char *file, const char *function, int lineno, FX::FXMemoryPool *heap, FX::FXuint alignment) throw(std::bad_alloc)
00228 {
00229 void *ret;
00230 if(!(ret=FX::malloc_dbg(file, function, lineno, size, heap, alignment))) throw std::bad_alloc();
00231 return ret;
00232 }
00233 inline FXDLLPUBLIC FXMALLOCATTR void *operator new[](size_t size, const char *file, const char *function, int lineno, FX::FXMemoryPool *heap, FX::FXuint alignment) throw(std::bad_alloc);
00234 inline FXDLLPUBLIC void *operator new[](size_t size, const char *file, const char *function, int lineno, FX::FXMemoryPool *heap, FX::FXuint alignment) throw(std::bad_alloc)
00235 {
00236 void *ret;
00237 if(!(ret=FX::malloc_dbg(file, function, lineno, size, heap, alignment))) throw std::bad_alloc();
00238 return ret;
00239 }
00240 inline FXDLLPUBLIC void operator delete(void *ptr, const char *file, const char *function, int lineno, FX::FXMemoryPool *heap, FX::FXuint alignment) throw()
00241 {
00242 if(ptr) FX::free(ptr, heap);
00243 }
00244 inline FXDLLPUBLIC void operator delete[](void *ptr, const char *file, const char *function, int lineno, FX::FXMemoryPool *heap, FX::FXuint alignment) throw()
00245 {
00246 if(ptr) FX::free(ptr, heap);
00247 }
00248 #endif
00249
00250 namespace FX {
00251
00252
00335 struct FXMemoryPoolPrivate;
00336 class FXAPI FXMemoryPool
00337 {
00338 friend FXAPI void *malloc(size_t size, FXMemoryPool *heap, FXuint alignment) throw();
00339 friend FXAPI void *malloc_dbg(const char *file, const char *function, int lineno, size_t size, FXMemoryPool *heap, FXuint alignment) throw();
00340 friend FXAPI void *calloc(size_t no, size_t _size, FXMemoryPool *heap, FXuint alignment) throw();
00341 friend FXAPI void *calloc_dbg(const char *file, const char *function, int lineno, size_t no, size_t _size, FXMemoryPool *heap, FXuint alignment) throw();
00342 friend FXAPI void *realloc(void *p, size_t size, FXMemoryPool *heap) throw();
00343 friend FXAPI void *realloc_dbg(const char *file, const char *function, int lineno, void *p, size_t size, FXMemoryPool *heap) throw();
00344 friend FXAPI void free(void *p, FXMemoryPool *heap) throw();
00345 FXMemoryPoolPrivate *p;
00346 FXMemoryPool(const FXMemoryPool &);
00347 FXMemoryPool &operator=(const FXMemoryPool &);
00348 public:
00350 static const FXuval minHeapVirtualSpace=1024*1024;
00352 struct Statistics
00353 {
00354 FXuval arena;
00355 FXuval freeChunks;
00356 FXuval fastChunks;
00357 FXuval mmapRegions;
00358 FXuval mmapBytes;
00359 FXuval maxAlloc;
00360 FXuval totalFast;
00361 FXuval totalAlloc;
00362 FXuval totalFree;
00363 FXuval keepCost;
00364 Statistics(FXuval a, FXuval b, FXuval c, FXuval d, FXuval e, FXuval f,
00365 FXuval g, FXuval h, FXuval i, FXuval j) : arena(a), freeChunks(b), fastChunks(c),
00366 mmapRegions(d), mmapBytes(e), maxAlloc(f), totalFast(g), totalAlloc(h),
00367 totalFree(i), keepCost(j) { }
00368 };
00375 FXMemoryPool(FXuval maximum=(FXuval)-1, const char *identifier=0, QThread *owner=0, bool lazydeleted=false);
00376 ~FXMemoryPool();
00378 FXuval size() const throw();
00380 FXuval maxsize() const throw();
00382 FXMALLOCATTR void *malloc(FXuval size, FXuint alignment=0) throw();
00384 FXMALLOCATTR void *calloc(FXuint no, FXuval size, FXuint alignment=0) throw();
00386 void free(void *blk, FXuint alignment=0) throw();
00390 FXMALLOCATTR void *realloc(void *blk, FXuval size) throw();
00392 static FXMemoryPool *poolFromBlk(void *blk) throw();
00393 public:
00395 static FXMALLOCATTR void *glmalloc(FXuval size, FXuint alignment=0) throw();
00398 static FXMALLOCATTR void *glcalloc(FXuval no, FXuval size, FXuint alignment=0) throw();
00400 static void glfree(void *blk, FXuint alignment=0) throw();
00404 static FXMALLOCATTR void *glrealloc(void *blk, FXuval size) throw();
00406 static bool gltrim(FXuval left) throw();
00408 static Statistics glstats() throw();
00410 static FXString glstatsAsString();
00411 public:
00413 static FXMemoryPool *current();
00415 static void setCurrent(FXMemoryPool *heap);
00416
00418 struct MemoryPoolInfo
00419 {
00420 bool deleted;
00421 QThread *owner;
00422 const char *identifier;
00423 FXuval maximum;
00424 FXuval allocated;
00425 };
00427 static QMemArray<MemoryPoolInfo> statistics();
00428 };
00429
00435 class FXMemPoolHold
00436 {
00437 FXMemoryPool *oldheap;
00438 public:
00439 FXMemPoolHold(FXMemoryPool *newheap) : oldheap(FXMemoryPool::current()) { FXMemoryPool::setCurrent(newheap); }
00440 ~FXMemPoolHold() { FXMemoryPool::setCurrent(oldheap); }
00441 };
00442
00443 }
00444
00447 extern "C" FXAPI FXMALLOCATTR void *tnfxmalloc(size_t size);
00450 extern "C" FXAPI FXMALLOCATTR void *tnfxcalloc(size_t no, size_t size);
00453 extern "C" FXAPI FXMALLOCATTR void *tnfxrealloc(void *p, size_t size);
00456 extern "C" FXAPI void tnfxfree(void *p);
00457
00458
00459
00460
00463 inline FXDLLPUBLIC FXMALLOCATTR void *operator new(size_t size) throw(std::bad_alloc);
00464 inline FXDLLPUBLIC void *operator new(size_t size) throw(std::bad_alloc)
00465 {
00466 void *ret;
00467 if(!(ret=FX::malloc(size))) throw std::bad_alloc();
00468 return ret;
00469 }
00472 inline FXDLLPUBLIC FXMALLOCATTR void *operator new[](size_t size) throw(std::bad_alloc);
00473 inline FXDLLPUBLIC void *operator new[](size_t size) throw(std::bad_alloc)
00474 {
00475 void *ret;
00476 if(!(ret=FX::malloc(size))) throw std::bad_alloc();
00477 return ret;
00478 }
00481 inline FXDLLPUBLIC void operator delete(void *p) throw()
00482 {
00483 if(p) FX::free(p);
00484 }
00487 inline FXDLLPUBLIC void operator delete[](void *p) throw()
00488 {
00489 if(p) FX::free(p);
00490 }
00491
00492
00493 #endif
00494 #endif