Eneboo - Documentación para desarrolladores
|
00001 // -*- C++ -*- 00002 00003 #ifndef _HOARDSUPERBLOCKHEADER_H_ 00004 #define _HOARDSUPERBLOCKHEADER_H_ 00005 00006 #include <cstdlib> 00007 00008 namespace Hoard { 00009 00010 template <class LockType, 00011 int SuperblockSize, 00012 typename HeapType> 00013 class HoardSuperblock; 00014 00015 template <class LockType, 00016 int SuperblockSize, 00017 typename HeapType> 00018 class HoardSuperblockHeader { 00019 public: 00020 00021 HoardSuperblockHeader (size_t sz, size_t bufferSize) 00022 : _magicNumber (MAGIC_NUMBER), 00023 _objectSize (sz), 00024 _objectSizeIsPowerOfTwo (!(sz & (sz - 1)) && sz), 00025 _totalObjects ((int) (bufferSize / sz)), 00026 _owner (NULL), 00027 _prev (NULL), 00028 _next (NULL), 00029 _reapableObjects (_totalObjects), 00030 _objectsFree (_totalObjects), 00031 _start ((char *) (this + 1)), 00032 _position (_start) 00033 { 00034 } 00035 00036 inline void * malloc (void) { 00037 assert (isValid()); 00038 void * ptr = reapAlloc(); 00039 if (!ptr) { 00040 ptr = freeListAlloc(); 00041 } 00042 assert ((size_t) ptr % sizeof(double) == 0); 00043 return ptr; 00044 } 00045 00046 inline void free (void * ptr) { 00047 assert (isValid()); 00048 _freeList.insert (reinterpret_cast<FreeSLList::Entry *>(ptr)); 00049 _objectsFree++; 00050 if (_objectsFree == _totalObjects) { 00051 clear(); 00052 } 00053 } 00054 00055 void clear (void) { 00056 assert (isValid()); 00057 // Clear out the freelist. 00058 _freeList.clear(); 00059 // All the objects are now free. 00060 _objectsFree = _totalObjects; 00061 _reapableObjects = _totalObjects; 00062 _position = _start; 00063 } 00064 00066 INLINE void * normalize (void * ptr) const { 00067 assert (isValid()); 00068 size_t offset = (size_t) ptr - (size_t) _start; 00069 void * p; 00070 00071 // Optimization note: the modulo operation (%) is *really* slow on 00072 // some architectures (notably x86-64). To reduce its overhead, we 00073 // optimize for the case when the size request is a power of two, 00074 // which is often enough to make a difference. 00075 00076 if (_objectSizeIsPowerOfTwo) { 00077 p = (void *) ((size_t) ptr - (offset & (_objectSize - 1))); 00078 } else { 00079 p = (void *) ((size_t) ptr - (offset % _objectSize)); 00080 } 00081 return p; 00082 } 00083 00084 00085 size_t getSize (void * ptr) const { 00086 assert (isValid()); 00087 size_t offset = (size_t) ptr - (size_t) _start; 00088 size_t newSize; 00089 if (_objectSizeIsPowerOfTwo) { 00090 newSize = _objectSize - (offset & (_objectSize - 1)); 00091 } else { 00092 newSize = _objectSize - (offset % _objectSize); 00093 } 00094 return newSize; 00095 } 00096 00097 size_t getObjectSize (void) const { 00098 return _objectSize; 00099 } 00100 00101 int getTotalObjects (void) const { 00102 return _totalObjects; 00103 } 00104 00105 int getObjectsFree (void) const { 00106 return _objectsFree; 00107 } 00108 00109 HeapType * getOwner (void) const { 00110 return _owner; 00111 } 00112 00113 void setOwner (HeapType * o) { 00114 _owner = o; 00115 } 00116 00117 bool isValid (void) const { 00118 return (_magicNumber == MAGIC_NUMBER); 00119 } 00120 00121 HoardSuperblock<LockType, SuperblockSize, HeapType> * getNext (void) const { 00122 return _next; 00123 } 00124 00125 HoardSuperblock<LockType, SuperblockSize, HeapType> * getPrev (void) const { 00126 return _prev; 00127 } 00128 00129 void setNext (HoardSuperblock<LockType, SuperblockSize, HeapType> * n) { 00130 _next = n; 00131 } 00132 00133 void setPrev (HoardSuperblock<LockType, SuperblockSize, HeapType> * p) { 00134 _prev = p; 00135 } 00136 00137 void lock (void) { 00138 _theLock.lock(); 00139 } 00140 00141 void unlock (void) { 00142 _theLock.unlock(); 00143 } 00144 00145 private: 00146 00147 MALLOC_FUNCTION INLINE void * reapAlloc (void) { 00148 assert (isValid()); 00149 assert (_position); 00150 // Reap mode. 00151 if (_reapableObjects > 0) { 00152 char * ptr = _position; 00153 _position = ptr + _objectSize; 00154 _reapableObjects--; 00155 _objectsFree--; 00156 return ptr; 00157 } else { 00158 return NULL; 00159 } 00160 } 00161 00162 MALLOC_FUNCTION INLINE void * freeListAlloc (void) { 00163 assert (isValid()); 00164 // Freelist mode. 00165 char * ptr = reinterpret_cast<char *>(_freeList.get()); 00166 if (ptr) { 00167 assert (_objectsFree >= 1); 00168 _objectsFree--; 00169 } 00170 return ptr; 00171 } 00172 00173 enum { MAGIC_NUMBER = 0xcafed00d }; 00174 00176 const size_t _magicNumber; 00177 00179 const size_t _objectSize; 00180 00182 const bool _objectSizeIsPowerOfTwo; 00183 00185 const int _totalObjects; 00186 00188 LockType _theLock; 00189 00191 HeapType * _owner; 00192 00194 HoardSuperblock<LockType, SuperblockSize, HeapType> * _prev; 00195 00197 HoardSuperblock<LockType, SuperblockSize, HeapType> * _next; 00198 00200 int _reapableObjects; 00201 00203 int _objectsFree; 00204 00206 char * _start; 00207 00209 char * _position; 00210 00212 FreeSLList _freeList; 00213 00214 private: 00215 00216 // Force alignment. 00217 union { 00218 char _dchar; 00219 short _dshort; 00220 int _dint; 00221 long _dlong; 00222 float _dfloat; 00223 double _ddouble; 00224 long double _dldouble; 00225 }; 00226 }; 00227 00228 } 00229 00230 #endif