Eneboo - Documentación para desarrolladores
src/hoard/src/heaplayers/experimental/bigchunk.h
Ir a la documentación de este archivo.
00001 /* -*- C++ -*- */
00002 
00003 #ifndef _BIGCHUNK_H_
00004 #define _BIGCHUNK_H_
00005 
00006 #include <assert.h>
00007 
00008 template <int chunkSize, int slotSize, class Super>
00009 class BigChunk {
00010 public:
00011 
00012   inline BigChunk (void);
00013 
00014   // Get and put slots.
00015   // Get returns NULL if there are no slots available.
00016   inline void * getSlot (void);
00017   inline void putSlot (void *);
00018 
00019   // How many slots are there in total?
00020   inline static int getNumSlots (void);
00021 
00022   // How many slots are available?
00023   inline int getNumSlotsFree (void);
00024 
00025   // How many slots are available?
00026   inline int getNumSlotsInUse (void);
00027 
00028   // Find a chunk given its slot.
00029   inline static BigChunk * getChunk (void *);
00030 
00031   class ChunkBlock {
00032   public:
00033     void setChunk (BigChunk * ch) { _myChunk = ch; }
00034     BigChunk * getChunk (void) { return _myChunk; }
00035     void setNext (ChunkBlock * n) { _next = n; }
00036     ChunkBlock * getNext (void) { return _next; }
00037   private:
00038     BigChunk * _myChunk;   // If allocated, point to the chunk.
00039     ChunkBlock * _next; // If not allocated, point to the next chunk block.
00040   };
00041 
00042   // Find a chunk block for a given pointer.
00043   static inline ChunkBlock * getChunkBlock (void * ptr) {
00044         assert (ptr != NULL);
00045         return (ChunkBlock *) ptr - 1;
00046   }
00047 
00048   void setHeap (Super * h) {
00049         heap = h;
00050   }
00051 
00052   inline Super * getHeap (void) {
00053         return heap;
00054   }
00055 
00056   // Add doubly linked-list operations.
00057   inline BigChunk * getNext (void);
00058   inline BigChunk * getPrev (void);
00059   inline void setNext (BigChunk *);
00060   inline void setPrev (BigChunk *);
00061 
00062 private:
00063 
00064   static inline size_t align (size_t sz) {
00065     return (sz + (sizeof(double) - 1)) & ~(sizeof(double) - 1);
00066   }
00067 
00068   ChunkBlock * freeSlots;
00069   int numSlotsAvailable;
00070   Super * heap;
00071   BigChunk * prev;
00072   BigChunk * next;
00073 };
00074 
00075 
00076 template <int chunkSize, int slotSize, class Super>
00077 BigChunk<chunkSize, slotSize, Super> * BigChunk<chunkSize, slotSize, Super>::getNext (void)
00078 {
00079   return next;
00080 }
00081 
00082 
00083 template <int chunkSize, int slotSize, class Super>
00084 BigChunk<chunkSize, slotSize, Super> * BigChunk<chunkSize, slotSize, Super>::getPrev (void)
00085 {
00086   return prev;
00087 }
00088 
00089 
00090 template <int chunkSize, int slotSize, class Super>
00091 void BigChunk<chunkSize, slotSize, Super>::setNext (BigChunk<chunkSize, slotSize, Super> * ptr)
00092 {
00093   next = ptr;
00094 }
00095 
00096 
00097 template <int chunkSize, int slotSize, class Super>
00098 void BigChunk<chunkSize, slotSize, Super>::setPrev (BigChunk<chunkSize, slotSize, Super> * ptr)
00099 {
00100   prev = ptr;
00101 }
00102 
00103 
00104 template <int chunkSize, int slotSize, class Super>
00105 BigChunk<chunkSize, slotSize, Super>::BigChunk (void)
00106   : freeSlots (NULL),
00107     numSlotsAvailable (getNumSlots()),
00108         prev (NULL),
00109         next (NULL)
00110 {
00111   //printf ("numSlots = %d\n", numSlots);
00112   int numSlots = getNumSlots();
00113   assert (numSlots > 0);
00114   const int blksize = align(sizeof(ChunkBlock) + slotSize);
00115   //printf ("blksize = %d\n", blksize);
00116   // Carve up the chunk into a number of slots.
00117   ChunkBlock * b = (ChunkBlock *) (this + 1);
00118   for (int i = 0; i < numSlots; i++) {
00119         assert ((unsigned long) b < ((unsigned long) (this + 1) + blksize * numSlots));
00120     new (b) ChunkBlock;
00121     b->setChunk (this);
00122         assert (b->getChunk() == this);
00123     b->setNext (freeSlots);
00124     freeSlots = b;
00125     b = (ChunkBlock *) ((char *) b + blksize);
00126   }
00127 }
00128 
00129 
00130 template <int chunkSize, int slotSize, class Super>
00131 void * BigChunk<chunkSize, slotSize, Super>::getSlot (void)
00132 {
00133   if (freeSlots == NULL) {
00134     assert (numSlotsAvailable == 0);
00135     return NULL;
00136   }
00137   assert (numSlotsAvailable > 0);
00138   assert (numSlotsAvailable <= getNumSlots());
00139   ChunkBlock * b = freeSlots;
00140   freeSlots = freeSlots->getNext();
00141   numSlotsAvailable--;
00142   b->setChunk (this); // FIX ME -- this should be unnecessary.
00143   b->setNext (NULL);
00144   void * ptr = (void *) (b + 1);
00145   BigChunk<chunkSize, slotSize, Super> * bch = getChunk(ptr);
00146   assert (bch == this);
00147   return (void *) (b + 1);
00148 }
00149 
00150 
00151 template <int chunkSize, int slotSize, class Super>
00152 void BigChunk<chunkSize, slotSize, Super>::putSlot (void * ptr)
00153 {
00154   assert (numSlotsAvailable >= 0);
00155   assert (numSlotsAvailable <= getNumSlots());
00156   ChunkBlock * b = getChunkBlock (ptr);
00157   assert (b->getChunk() == this);
00158   b->setNext (freeSlots);
00159   freeSlots = b;
00160   numSlotsAvailable++;
00161   assert (numSlotsAvailable > 0);
00162   assert (numSlotsAvailable <= getNumSlots());
00163 }
00164 
00165 
00166 template <int chunkSize, int slotSize, class Super>
00167 int BigChunk<chunkSize, slotSize, Super>::getNumSlots (void)
00168 {
00169   return ((chunkSize - sizeof(BigChunk)) / align (sizeof(ChunkBlock) + slotSize));
00170 }
00171 
00172 
00173 template <int chunkSize, int slotSize, class Super>
00174 int BigChunk<chunkSize, slotSize, Super>::getNumSlotsFree (void)
00175 {
00176   return numSlotsAvailable;
00177 }
00178 
00179 
00180 template <int chunkSize, int slotSize, class Super>
00181 int BigChunk<chunkSize, slotSize, Super>::getNumSlotsInUse (void)
00182 {
00183   return getNumSlots() - numSlotsAvailable;
00184 }
00185 
00186 
00187 template <int chunkSize, int slotSize, class Super>
00188 BigChunk<chunkSize, slotSize, Super> * BigChunk<chunkSize, slotSize, Super>::getChunk (void * ptr)
00189 {
00190   ChunkBlock * ch = getChunkBlock (ptr);
00191   return ch->getChunk();
00192 }
00193 
00194 #endif
 Todo Clases Namespaces Archivos Funciones Variables 'typedefs' Enumeraciones Valores de enumeraciones Propiedades Amigas 'defines'