Eneboo - Documentación para desarrolladores
|
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 }