Eneboo - Documentación para desarrolladores
src/hoard/src/hoardsuperblockheader.h
Ir a la documentación de este archivo.
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
 Todo Clases Namespaces Archivos Funciones Variables 'typedefs' Enumeraciones Valores de enumeraciones Propiedades Amigas 'defines'