Eneboo - Documentación para desarrolladores
src/hoard/src/heaplayers/experimental/chunk.h
Ir a la documentación de este archivo.
00001 /* -*- C++ -*- */
00002 
00003 #ifndef _CHUNK_H_
00004 #define _CHUNK_H_
00005 
00006 /*
00007 
00008   Heap Layers: An Extensible Memory Allocation Infrastructure
00009   
00010   Copyright (C) 2000-2003 by Emery Berger
00011   http://www.cs.umass.edu/~emery
00012   emery@cs.umass.edu
00013   
00014   This program is free software; you can redistribute it and/or modify
00015   it under the terms of the GNU General Public License as published by
00016   the Free Software Foundation; either version 2 of the License, or
00017   (at your option) any later version.
00018   
00019   This program is distributed in the hope that it will be useful,
00020   but WITHOUT ANY WARRANTY; without even the implied warranty of
00021   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00022   GNU General Public License for more details.
00023   
00024   You should have received a copy of the GNU General Public License
00025   along with this program; if not, write to the Free Software
00026   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00027 
00028 */
00029 
00030 #include <assert.h>
00031 
00032 namespace HL {
00033 
00034 template <int chunkSize, int slotSize>
00035 class Chunk {
00036 public:
00037 
00038   inline Chunk (void);
00039 
00040   // Get and put slots.
00041   // Get returns NULL if there are no slots available.
00042   inline void * getSlot (void);
00043   inline void putSlot (void *);
00044 
00045   // How many slots are there in total?
00046   inline static int getNumSlots (void);
00047 
00048   // How many slots are available?
00049   inline int getNumSlotsFree (void);
00050 
00051   // How many slots are available?
00052   inline int getNumSlotsInUse (void);
00053 
00054   // Find a chunk given its slot.
00055   inline static Chunk * getChunk (void *);
00056 
00057   class ChunkBlock {
00058   public:
00059     void setChunk (Chunk * ch) { _myChunk = ch; }
00060     Chunk * getChunk (void) { return _myChunk; }
00061     void setNext (ChunkBlock * n) { _next = n; }
00062     ChunkBlock * getNext (void) { return _next; }
00063   private:
00064     Chunk * _myChunk;   // If allocated, point to the chunk.
00065     ChunkBlock * _next; // If not allocated, point to the next chunk block.
00066   };
00067 
00068   // Find a chunk block for a given pointer.
00069   static inline ChunkBlock * getChunkBlock (void * ptr) {
00070         assert (ptr != NULL);
00071         return (ChunkBlock *) ptr - 1;
00072   }
00073 
00074 private:
00075 
00076   ChunkBlock * freeSlots;
00077   int numSlotsAvailable;
00078 
00079   static inline size_t align (size_t sz) {
00080     return (sz + (sizeof(double) - 1)) & ~(sizeof(double) - 1);
00081   }
00082 
00083 };
00084 
00085 template <int chunkSize, int slotSize>
00086 Chunk<chunkSize, slotSize>::Chunk (void)
00087   : freeSlots (NULL),
00088     numSlotsAvailable (getNumSlots())
00089 {
00090   //printf ("numSlots = %d\n", numSlots);
00091   int numSlots = getNumSlots();
00092   assert (numSlots > 0);
00093   const int blksize = align(sizeof(ChunkBlock) + slotSize);
00094   //printf ("blksize = %d\n", blksize);
00095   // Carve up the chunk into a number of slots.
00096   ChunkBlock * b = (ChunkBlock *) (this + 1);
00097   for (int i = 0; i < numSlots; i++) {
00098         assert ((unsigned long) b < ((unsigned long) (this + 1) + blksize * numSlots));
00099     new (b) ChunkBlock;
00100     b->setChunk (this);
00101         assert (b->getChunk() == this);
00102     b->setNext (freeSlots);
00103     freeSlots = b;
00104     b = (ChunkBlock *) ((char *) b + blksize);
00105   }
00106 }
00107 
00108 
00109 template <int chunkSize, int slotSize>
00110 void * Chunk<chunkSize, slotSize>::getSlot (void)
00111 {
00112   if (freeSlots == NULL) {
00113     assert (numSlotsAvailable == 0);
00114     return NULL;
00115   }
00116   assert (numSlotsAvailable > 0);
00117   ChunkBlock * b = freeSlots;
00118   freeSlots = freeSlots->getNext();
00119   numSlotsAvailable--;
00120   b->setChunk (this); // FIX ME -- this should be unnecessary.
00121   b->setNext (NULL);
00122   void * ptr = (void *) (b + 1);
00123   Chunk<chunkSize, slotSize> * bch = getChunk(ptr);
00124   assert (bch == this);
00125   return (void *) (b + 1);
00126 }
00127 
00128 
00129 template <int chunkSize, int slotSize>
00130 void Chunk<chunkSize, slotSize>::putSlot (void * ptr)
00131 {
00132   ChunkBlock * b = getChunkBlock (ptr);
00133   assert (b->getChunk() == this);
00134   b->setNext (freeSlots);
00135   freeSlots = b;
00136   numSlotsAvailable++;
00137   assert (numSlotsAvailable <= getNumSlots());
00138 }
00139 
00140 
00141 template <int chunkSize, int slotSize>
00142 int Chunk<chunkSize, slotSize>::getNumSlots (void)
00143 {
00144   return ((chunkSize - sizeof(Chunk)) / align (sizeof(ChunkBlock) + slotSize));
00145 }
00146 
00147 
00148 template <int chunkSize, int slotSize>
00149 int Chunk<chunkSize, slotSize>::getNumSlotsFree (void)
00150 {
00151   return numSlotsAvailable;
00152 }
00153 
00154 
00155 template <int chunkSize, int slotSize>
00156 int Chunk<chunkSize, slotSize>::getNumSlotsInUse (void)
00157 {
00158   return getNumSlots() - numSlotsAvailable;
00159 }
00160 
00161 
00162 template <int chunkSize, int slotSize>
00163 Chunk<chunkSize, slotSize> * Chunk<chunkSize, slotSize>::getChunk (void * ptr)
00164 {
00165   ChunkBlock * ch = getChunkBlock (ptr);
00166   return ch->getChunk();
00167 }
00168 
00169 };
00170 
00171 #endif
 Todo Clases Namespaces Archivos Funciones Variables 'typedefs' Enumeraciones Valores de enumeraciones Propiedades Amigas 'defines'