00001
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
00015
00016 inline void * getSlot (void);
00017 inline void putSlot (void *);
00018
00019
00020 inline static int getNumSlots (void);
00021
00022
00023 inline int getNumSlotsFree (void);
00024
00025
00026 inline int getNumSlotsInUse (void);
00027
00028
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;
00039 ChunkBlock * _next;
00040 };
00041
00042
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
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
00112 int numSlots = getNumSlots();
00113 assert (numSlots > 0);
00114 const int blksize = align(sizeof(ChunkBlock) + slotSize);
00115
00116
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);
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