00001
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
00050
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
00063
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
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
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
00093 _parentHeap->free (ptr);
00094 }
00095
00096 } else {
00097
00098 }
00099 }
00100
00101 void clear (void) {
00102
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
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 }