csutil/blockallocator.h Source File (Crystal Space 2.0 Public API Reference)

| ## Public API Reference

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

- File List
- File Members

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__