| ## Public API Reference

- Main Page
- Modules
- Namespaces
- Classes
- Files
- Related Pages

- File List
- File Members

# csutil/allocator.h

Go to the documentation of this file.

    00001 /*
    00002     Copyright (C) 2006 by Frank Richter
    00003
    00004     This library is free software; you can redistribute it and/or
    00005     modify it under the terms of the GNU Library General Public
    00006     License as published by the Free Software Foundation; either
    00007     version 2 of the License, or (at your option) any later version.
    00008
    00009     This library is distributed in the hope that it will be useful,
    00010     but WITHOUT ANY WARRANTY; without even the implied warranty of
    00011     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00012     Library General Public License for more details.
    00013
    00014     You should have received a copy of the GNU Library General Public
    00015     License along with this library; if not, write to the Free
    00016     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
    00017 */
    00018
    00019 #ifndef __CS_CSUTIL_ALLOCATOR_H__
    00020 #define __CS_CSUTIL_ALLOCATOR_H__
    00021
    00026 #include "csutil/alignedalloc.h"
    00027 #include "csutil/memdebug.h"
    00028
    00032 namespace CS
    00033 {
    00034   namespace Memory
    00035   {
    00039     class AllocatorMalloc
    00040     {
    00041     #ifdef CS_MEMORY_TRACKER
    00043       csMemTrackerInfo* mti;
    00044     #endif
    00045     public:
    00046     #ifdef CS_MEMORY_TRACKER
    00047       AllocatorMalloc() : mti (0) {}
    00048     #endif
    00050       void* Alloc (const size_t n)
    00051       {
    00052       #ifdef CS_MEMORY_TRACKER
    00053         size_t* p = (size_t*)cs_malloc (n + sizeof (size_t));
    00054         *p = n;
    00055         p++;
    00056         if (mti) mtiUpdateAmount (mti, 1, int (n));
    00057         return p;
    00058       #else
    00059         return cs_malloc (n);
    00060       #endif
    00061       }
    00063       void Free (void* p)
    00064       {
    00065       #ifdef CS_MEMORY_TRACKER
    00066         size_t* x = (size_t*)p;
    00067         x--;
    00068         size_t allocSize = *x;
    00069         cs_free (x);
    00070         if (mti) mtiUpdateAmount (mti, -1, -int (allocSize));
    00071       #else
    00072         cs_free (p);
    00073       #endif
    00074       }
    00076       void* Realloc (void* p, size_t newSize)
    00077       {
    00078       #ifdef CS_MEMORY_TRACKER
    00079         if (p == 0) return Alloc (newSize);
    00080         size_t* x = (size_t*)p;
    00081         x--;
    00082         if (mti) mtiUpdateAmount (mti, -1, -int (*x));
    00083         size_t* np = (size_t*)cs_realloc (x, newSize + sizeof (size_t));
    00084         *np = newSize;
    00085         np++;
    00086         if (mti) mtiUpdateAmount (mti, 1, int (newSize));
    00087         return np;
    00088       #else
    00089         return cs_realloc (p, newSize);
    00090       #endif
    00091       }
    00093       void SetMemTrackerInfo (const char* info)
    00094       {
    00095       #ifdef CS_MEMORY_TRACKER
    00096         mti = mtiRegister (info);
    00097       #else
    00098         (void)info;
    00099       #endif
    00100       }
    00101     };
    00102
    00119     template<typename T, size_t N, class ExcessAllocator = AllocatorMalloc>
    00120     class LocalBufferAllocator : public ExcessAllocator
    00121     {
    00122       static const size_t localSize = N * sizeof (T);
    00123       uint8 localBuf[localSize];
    00124     #ifdef CS_DEBUG
    00125       bool allocation;
    00126     #endif
    00127     public:
    00128     #ifdef CS_DEBUG
    00129       LocalBufferAllocator () : allocation (false) {}
    00130       LocalBufferAllocator (const ExcessAllocator& xalloc) :
    00131         ExcessAllocator (xalloc), allocation (false) {}
    00132     #else
    00133       LocalBufferAllocator () {}
    00134       LocalBufferAllocator (const ExcessAllocator& xalloc) :
    00135         ExcessAllocator (xalloc) {}
    00136     #endif
    00137       T* Alloc (size_t allocSize)
    00138       {
    00139       #ifdef CS_DEBUG
    00140         CS_ASSERT_MSG("LocalBufferAllocator only allows one allocation a time!",
    00141           !allocation);
    00142         allocation = true;
    00143       #endif
    00144         if (allocSize <= localSize)
    00145           return (T*)localBuf;
    00146         else
    00147           return (T*)ExcessAllocator::Alloc (allocSize);
    00148       }
    00149
    00150       void Free (T* mem)
    00151       {
    00152       #ifdef CS_DEBUG
    00153         CS_ASSERT_MSG("Free() without prior allocation",
    00154           allocation);
    00155         allocation = false;
    00156       #endif
    00157         if (mem != (T*)localBuf) ExcessAllocator::Free (mem);
    00158       }
    00159
    00160       // The 'relevantcount' parameter should be the number of items
    00161       // in the old array that are initialized.
    00162       void* Realloc (void* p, size_t newSize)
    00163       {
    00164       #ifdef CS_DEBUG
    00165         CS_ASSERT_MSG("Realloc() without prior allocation",
    00166           allocation);
    00167       #endif
    00168         if (p == localBuf)
    00169         {
    00170           if (newSize <= localSize)
    00171             return p;
    00172           else
    00173           {
    00174             p = ExcessAllocator::Alloc (newSize);
    00175             memcpy (p, localBuf, localSize);
    00176             return p;
    00177           }
    00178         }
    00179         else
    00180         {
    00181           if (newSize <= localSize)
    00182           {
    00183             memcpy (localBuf, p, newSize);
    00184             ExcessAllocator::Free (p);
    00185             return localBuf;
    00186           }
    00187           else
    00188             return ExcessAllocator::Realloc (p, newSize);
    00189         }
    00190       }
    00191       using ExcessAllocator::SetMemTrackerInfo;
    00192     };
    00193
    00199     template <size_t A = 1>
    00200     class AllocatorAlign
    00201     {
    00202     public:
    00206       static inline void* Alloc (size_t size)
    00207       {
    00208         return AlignedMalloc (size, A);
    00209       }
    00210
    00215       static inline void Free (void* p)
    00216       {
    00217         AlignedFree (p);
    00218       }
    00219
    00220       void* Realloc (void* p, size_t newSize)
    00221       {
    00222         return AlignedRealloc (p, newSize, A);
    00223       }
    00224
    00225       void SetMemTrackerInfo (const char* info)
    00226       {
    00227         (void)info;
    00228       }
    00229     };
    00230
    00236     template<typename T, typename Allocator>
    00237     struct AllocatorPointerWrapper : public Allocator
    00238     {
    00240       T* p;
    00241
    00242       AllocatorPointerWrapper () {}
    00243       AllocatorPointerWrapper (const Allocator& alloc) :
    00244         Allocator (alloc) {}
    00245       AllocatorPointerWrapper (T* p) : p (p) {}
    00246       AllocatorPointerWrapper (const Allocator& alloc, T* p) :
    00247         Allocator (alloc), p (p) {}
    00248     };
    00249   } // namespace Memory
    00250 } // namespace CS
    00251
    00254 #endif // __CS_CSUTIL_ALLOCATOR_H__