Eneboo - Documentación para desarrolladores
src/hoard/src/tlab.h
Ir a la documentación de este archivo.
00001 // -*- C++ -*-
00002 
00010 #include "dllist.h"
00011 #include "array.h"
00012 
00013 namespace Hoard {
00014 
00015 template <int NumBins,
00016           int (*getSizeClass) (size_t),
00017           size_t (*getClassSize) (const int),
00018           int LargestObject,
00019           int LocalHeapThreshold,
00020           class SuperblockType,
00021           int SuperblockSize,
00022           class ParentHeap>
00023 
00024 class ThreadLocalAllocationBuffer {
00025 
00026 public:
00027 
00028   ThreadLocalAllocationBuffer (ParentHeap * parent)
00029     : _parentHeap (parent),
00030       _localHeapBytes (0)
00031   {
00032   }
00033 
00034   ~ThreadLocalAllocationBuffer (void) {
00035     clear();
00036   }
00037 
00038   inline static size_t getSize (void * ptr) {
00039     return getSuperblock(ptr)->getSize (ptr);
00040   }
00041 
00042   inline void * malloc (size_t sz) {
00043 #if 1
00044     if (sz < 2 * sizeof(size_t)) {
00045       sz = 2 * sizeof(size_t);
00046     }
00047     sz = align (sz);
00048 #endif
00049     // Get memory from the local heap,
00050     // and deduct that amount from the local heap bytes counter.
00051     if (sz <= LargestObject) {
00052       int c = getSizeClass (sz);
00053       void * ptr = _localHeap(c).get();
00054       if (ptr) {
00055         assert (_localHeapBytes >= sz);
00056         _localHeapBytes -= sz; 
00057         assert (getSize(ptr) >= sz);
00058         return ptr;
00059       }
00060     }
00061 
00062     // No more local memory (for this size, at least).
00063     // Now get the memory from our parent.
00064     void * ptr = _parentHeap->malloc (sz);
00065     return ptr;
00066   }
00067 
00068 
00069   inline void free (void * ptr) {
00070     if (!ptr) {
00071       return;
00072     }
00073     const SuperblockType * s = getSuperblock (ptr);
00074     // If this isn't a valid superblock, just return.
00075 
00076     if (s->isValidSuperblock()) {
00077 
00078       ptr = s->normalize (ptr);
00079       const size_t sz = s->getObjectSize ();
00080 
00081       if ((sz <= LargestObject) && (sz + _localHeapBytes <= LocalHeapThreshold)) {
00082         // Free small objects locally, unless we are out of space.
00083 
00084         assert (getSize(ptr) >= sizeof(HL::DLList::Entry *));
00085         int c = getSizeClass (sz);
00086 
00087         _localHeap(c).insert ((HL::DLList::Entry *) ptr);
00088         _localHeapBytes += sz;
00089           
00090       } else {
00091 
00092         // Free it to the parent.
00093         _parentHeap->free (ptr);
00094       }
00095 
00096     } else {
00097       // Illegal pointer.
00098     }
00099   }
00100 
00101   void clear (void) {
00102     // Free every object to the 'parent' heap.
00103     int i = NumBins - 1;
00104     while ((_localHeapBytes > 0) && (i >= 0)) {
00105       const size_t sz = getClassSize (i);
00106       while (!_localHeap(i).isEmpty()) {
00107         HL::DLList::Entry * e = _localHeap(i).get();
00108         _parentHeap->free (e);
00109         _localHeapBytes -= sz;
00110       }
00111       i--;
00112     }
00113   }
00114 
00115   static inline SuperblockType * getSuperblock (void * ptr) {
00116     return SuperblockType::getSuperblock (ptr);
00117   }
00118 
00119 private:
00120 
00121   inline static size_t align (size_t sz) {
00122     return (sz + (sizeof(double) - 1)) & ~(sizeof(double) - 1);
00123   }
00124   
00125 
00126   // Disable assignment and copying.
00127 
00128   ThreadLocalAllocationBuffer (const ThreadLocalAllocationBuffer&);
00129   ThreadLocalAllocationBuffer& operator=(const ThreadLocalAllocationBuffer&);
00130 
00132   ParentHeap * _parentHeap;
00133 
00135   size_t _localHeapBytes;
00136 
00138   Array<NumBins, HL::DLList> _localHeap;
00139 
00140 };
00141 
00142 }
 Todo Clases Namespaces Archivos Funciones Variables 'typedefs' Enumeraciones Valores de enumeraciones Propiedades Amigas 'defines'