CrystalSpace

Public API Reference

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__

Generated for Crystal Space by doxygen 1.4.7