CrystalSpace

Public API Reference

csutil/blockallocator.h
Go to the documentation of this file.
00001 /*
00002   Crystal Space Generic Object Block Allocator
00003   Copyright (C) 2005 by Eric Sunshine <sunshine@sunshineco.com>
00004             (C) 2006 by Frank Richter
00005 
00006   This library is free software; you can redistribute it and/or
00007   modify it under the terms of the GNU Library General Public
00008   License as published by the Free Software Foundation; either
00009   version 2 of the License, or (at your option) any later version.
00010 
00011   This library is distributed in the hope that it will be useful,
00012   but WITHOUT ANY WARRANTY; without even the implied warranty of
00013   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014   Library General Public License for more details.
00015 
00016   You should have received a copy of the GNU Library General Public
00017   License along with this library; if not, write to the Free
00018   Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019 */
00020 #ifndef __CSUTIL_BLOCKALLOCATOR_H__
00021 #define __CSUTIL_BLOCKALLOCATOR_H__
00022 
00027 #include "csutil/fixedsizeallocator.h"
00028 #include "csutil/metautils.h"
00029 #include "csutil/custom_new_disable.h"
00030 
00037 template<typename T>
00038 class csBlockAllocatorDisposeDelete
00039 {
00040 public:
00044   template<typename BA>
00045   csBlockAllocatorDisposeDelete (const BA&, bool legit)
00046   { (void)legit; }
00048   void Dispose (void* p) 
00049   {
00050     ((T*)p)->~T();
00051   }
00052 };
00053 
00058 template<typename T>
00059 class csBlockAllocatorDisposeLeaky
00060 {
00061   bool doWarn;
00062 #ifdef CS_DEBUG
00063   const char* parentClass;
00064   const void* parent;
00065   size_t count;
00066 #endif
00067 public:
00068 #ifdef CS_DEBUG
00069 
00076   template<typename BA>
00077   csBlockAllocatorDisposeLeaky (const BA& ba, bool legit) :
00078     doWarn (!legit), parentClass (typeid(BA).name()), parent (&ba),
00079     count (0)
00080   { 
00081   }
00082 #else
00083   template<typename BA>
00084   csBlockAllocatorDisposeLeaky (const BA&, bool legit) : doWarn (!legit)
00085   { }
00086 #endif
00087   ~csBlockAllocatorDisposeLeaky()
00088   {
00089 #ifdef CS_DEBUG
00090     if ((count > 0) && doWarn)
00091     {
00092       csPrintfErr("%s %p leaked %zu objects.\n", parentClass, (void*)this, 
00093         count);
00094     }
00095 #endif
00096   }
00098   void Dispose (void* p) 
00099   {
00100     if (!doWarn) ((T*)p)->~T();
00101 #ifdef CS_DEBUG
00102     count++;
00103 #endif
00104   }
00105 };
00106 
00110 template<typename T>
00111 struct csBlockAllocatorSizeObject
00112 {
00113   static const unsigned int value = sizeof(T);
00114 };
00115 
00119 template<typename T, unsigned int Alignment>
00120 struct csBlockAllocatorSizeObjectAlign
00121 {
00122   static const unsigned int value = CS::Meta::AlignSize<T, Alignment>::value;
00123 };
00141 template <class T,
00142   typename Allocator = CS::Memory::AllocatorMalloc, 
00143   typename ObjectDispose = csBlockAllocatorDisposeDelete<T>,
00144   typename SizeComputer = csBlockAllocatorSizeObject<T>
00145 >
00146 class csBlockAllocator : 
00147   public csFixedSizeAllocator<
00148     SizeComputer::value,
00149     Allocator>
00150 {
00151 public:
00152   typedef csBlockAllocator<T, Allocator, ObjectDispose, SizeComputer> ThisType;
00153   typedef T ValueType;
00154   typedef Allocator AllocatorType;
00155 
00156 protected:
00157   typedef csFixedSizeAllocator<SizeComputer::value, Allocator> superclass;
00158 
00159 private:
00160   void* Alloc (size_t /*n*/) { return 0; }                       // Illegal
00161   void* Alloc (void* /*p*/, size_t /*newSize*/) { return 0; }   // Illegal
00162   void SetMemTrackerInfo (const char* /*info*/) { }             // Illegal
00163 public:
00183   csBlockAllocator(size_t nelem = 32) : superclass (nelem)
00184   {
00185 #ifdef CS_MEMORY_TRACKER
00186     superclass::blocks.SetMemTrackerInfo (typeid(*this).name());
00187 #endif
00188   }
00189 
00193   ~csBlockAllocator()
00194   {
00195     ObjectDispose dispose (*this, false);
00196     DisposeAll (dispose);
00197   }
00198 
00204   void Empty ()
00205   {
00206     ObjectDispose dispose (*this, true);
00207     FreeAll (dispose);
00208   }
00209 
00215   void DeleteAll ()
00216   {
00217     ObjectDispose dispose (*this, true);
00218     DisposeAll (dispose);
00219   }
00220 
00225   T* Alloc ()
00226   {
00227     return new (superclass::Alloc()) T;
00228   }
00229 
00234   template<typename A1, typename A2>
00235   T* Alloc (A1& a1, A2& a2)
00236   {
00237     return new (superclass::Alloc()) T (a1, a2);
00238   }
00239 
00244   template<typename A1, typename A2, typename A3>
00245   T* Alloc (A1& a1, A2& a2, A3& a3)
00246   {
00247     return new (superclass::Alloc()) T (a1, a2, a3);
00248   }
00249 
00254   template<typename A1>
00255   T* Alloc (A1& a1)
00256   {
00257     return new (superclass::Alloc()) T (a1);
00258   }
00259 
00264   void Free (T* p)
00265   {
00266     ObjectDispose dispose (*this, true);
00267     superclass::Free (dispose, p);
00268   }
00274   bool TryFree (T* p)
00275   {
00276     ObjectDispose dispose (*this, true);
00277     return superclass::TryFree (dispose, p);
00278   }
00279 };
00280 
00281 namespace CS
00282 {
00283   namespace Memory
00284   {
00290     template <class T,
00291       typename Allocator = AllocatorMalloc, 
00292       typename ObjectDispose = csBlockAllocatorDisposeDelete<T>,
00293       typename SizeComputer = csBlockAllocatorSizeObject<T>
00294     >
00295     class BlockAllocatorSafe : 
00296       public AllocatorSafe<csBlockAllocator<T, Allocator, ObjectDispose,
00297         SizeComputer> >
00298     {
00299     protected:
00300       typedef csBlockAllocator<T, Allocator,
00301         ObjectDispose, SizeComputer> WrappedAllocatorType;
00302       typedef AllocatorSafe<WrappedAllocatorType> AllocatorSafeType;
00303     public:
00304       BlockAllocatorSafe (size_t nelem = 32) : AllocatorSafeType (nelem)
00305       {
00306       }
00307     
00308       void Empty ()
00309       {
00310         CS::Threading::RecursiveMutexScopedLock lock (AllocatorSafeType::mutex);
00311         WrappedAllocatorType::Empty ();
00312       }
00313     
00314       void DeleteAll ()
00315       {
00316         CS::Threading::RecursiveMutexScopedLock lock (AllocatorSafeType::mutex);
00317         WrappedAllocatorType::DeleteAll ();
00318       }
00319       
00320       void Compact()
00321       {
00322         CS::Threading::RecursiveMutexScopedLock lock (AllocatorSafeType::mutex);
00323         WrappedAllocatorType::Compact();
00324       }
00325     
00326       T* Alloc ()
00327       {
00328         CS::Threading::RecursiveMutexScopedLock lock (AllocatorSafeType::mutex);
00329         return WrappedAllocatorType::Alloc ();
00330       }
00331     
00332       template<typename A1, typename A2>
00333       T* Alloc (A1& a1, A2& a2)
00334       {
00335         CS::Threading::RecursiveMutexScopedLock lock (AllocatorSafeType::mutex);
00336         return WrappedAllocatorType::Alloc (a1, a2);
00337       }
00338     
00339       template<typename A1, typename A2, typename A3>
00340       T* Alloc (A1& a1, A2& a2, A3& a3)
00341       {
00342         CS::Threading::RecursiveMutexScopedLock lock (AllocatorSafeType::mutex);
00343         return WrappedAllocatorType::Alloc (a1, a2, a3);
00344       }
00345     
00346       template<typename A1>
00347       T* Alloc (A1& a1)
00348       {
00349         CS::Threading::RecursiveMutexScopedLock lock (AllocatorSafeType::mutex);
00350         return WrappedAllocatorType::Alloc (a1);
00351       }
00352     
00353       void Free (T* p)
00354       {
00355         CS::Threading::RecursiveMutexScopedLock lock (AllocatorSafeType::mutex);
00356         WrappedAllocatorType::Free (p);
00357       }
00358       bool TryFree (T* p)
00359       {
00360         CS::Threading::RecursiveMutexScopedLock lock (AllocatorSafeType::mutex);
00361         return WrappedAllocatorType::TryFree (p);
00362       }
00363     };
00364   } // namespace Memory
00365 } // namespace CS
00366   
00369 #include "csutil/custom_new_enable.h"
00370 
00371 #endif // __CSUTIL_BLOCKALLOCATOR_H__

Generated for Crystal Space 2.0 by doxygen 1.7.6.1