"Fossies" - the Fresh Open Source Software Archive

Member "heaplayers-351/heaplayers/experimental/chunk.h" (4 May 2006, 4424 Bytes) of package /linux/misc/old/heaplayers_3_5_1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "chunk.h" see the Fossies "Dox" file reference documentation.

    1 /* -*- C++ -*- */
    2 
    3 #ifndef _CHUNK_H_
    4 #define _CHUNK_H_
    5 
    6 /*
    7 
    8   Heap Layers: An Extensible Memory Allocation Infrastructure
    9   
   10   Copyright (C) 2000-2003 by Emery Berger
   11   http://www.cs.umass.edu/~emery
   12   emery@cs.umass.edu
   13   
   14   This program is free software; you can redistribute it and/or modify
   15   it under the terms of the GNU General Public License as published by
   16   the Free Software Foundation; either version 2 of the License, or
   17   (at your option) any later version.
   18   
   19   This program is distributed in the hope that it will be useful,
   20   but WITHOUT ANY WARRANTY; without even the implied warranty of
   21   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   22   GNU General Public License for more details.
   23   
   24   You should have received a copy of the GNU General Public License
   25   along with this program; if not, write to the Free Software
   26   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   27 
   28 */
   29 
   30 #include <assert.h>
   31 
   32 namespace HL {
   33 
   34 template <int chunkSize, int slotSize>
   35 class Chunk {
   36 public:
   37 
   38   inline Chunk (void);
   39 
   40   // Get and put slots.
   41   // Get returns NULL if there are no slots available.
   42   inline void * getSlot (void);
   43   inline void putSlot (void *);
   44 
   45   // How many slots are there in total?
   46   inline static int getNumSlots (void);
   47 
   48   // How many slots are available?
   49   inline int getNumSlotsFree (void);
   50 
   51   // How many slots are available?
   52   inline int getNumSlotsInUse (void);
   53 
   54   // Find a chunk given its slot.
   55   inline static Chunk * getChunk (void *);
   56 
   57   class ChunkBlock {
   58   public:
   59     void setChunk (Chunk * ch) { _myChunk = ch; }
   60     Chunk * getChunk (void) { return _myChunk; }
   61     void setNext (ChunkBlock * n) { _next = n; }
   62     ChunkBlock * getNext (void) { return _next; }
   63   private:
   64     Chunk * _myChunk;   // If allocated, point to the chunk.
   65     ChunkBlock * _next; // If not allocated, point to the next chunk block.
   66   };
   67 
   68   // Find a chunk block for a given pointer.
   69   static inline ChunkBlock * getChunkBlock (void * ptr) {
   70     assert (ptr != NULL);
   71     return (ChunkBlock *) ptr - 1;
   72   }
   73 
   74 private:
   75 
   76   ChunkBlock * freeSlots;
   77   int numSlotsAvailable;
   78 
   79   static inline size_t align (size_t sz) {
   80     return (sz + (sizeof(double) - 1)) & ~(sizeof(double) - 1);
   81   }
   82 
   83 };
   84 
   85 template <int chunkSize, int slotSize>
   86 Chunk<chunkSize, slotSize>::Chunk (void)
   87   : freeSlots (NULL),
   88     numSlotsAvailable (getNumSlots())
   89 {
   90   //printf ("numSlots = %d\n", numSlots);
   91   int numSlots = getNumSlots();
   92   assert (numSlots > 0);
   93   const int blksize = align(sizeof(ChunkBlock) + slotSize);
   94   //printf ("blksize = %d\n", blksize);
   95   // Carve up the chunk into a number of slots.
   96   ChunkBlock * b = (ChunkBlock *) (this + 1);
   97   for (int i = 0; i < numSlots; i++) {
   98     assert ((unsigned long) b < ((unsigned long) (this + 1) + blksize * numSlots));
   99     new (b) ChunkBlock;
  100     b->setChunk (this);
  101     assert (b->getChunk() == this);
  102     b->setNext (freeSlots);
  103     freeSlots = b;
  104     b = (ChunkBlock *) ((char *) b + blksize);
  105   }
  106 }
  107 
  108 
  109 template <int chunkSize, int slotSize>
  110 void * Chunk<chunkSize, slotSize>::getSlot (void)
  111 {
  112   if (freeSlots == NULL) {
  113     assert (numSlotsAvailable == 0);
  114     return NULL;
  115   }
  116   assert (numSlotsAvailable > 0);
  117   ChunkBlock * b = freeSlots;
  118   freeSlots = freeSlots->getNext();
  119   numSlotsAvailable--;
  120   b->setChunk (this); // FIX ME -- this should be unnecessary.
  121   b->setNext (NULL);
  122   void * ptr = (void *) (b + 1);
  123   Chunk<chunkSize, slotSize> * bch = getChunk(ptr);
  124   assert (bch == this);
  125   return (void *) (b + 1);
  126 }
  127 
  128 
  129 template <int chunkSize, int slotSize>
  130 void Chunk<chunkSize, slotSize>::putSlot (void * ptr)
  131 {
  132   ChunkBlock * b = getChunkBlock (ptr);
  133   assert (b->getChunk() == this);
  134   b->setNext (freeSlots);
  135   freeSlots = b;
  136   numSlotsAvailable++;
  137   assert (numSlotsAvailable <= getNumSlots());
  138 }
  139 
  140 
  141 template <int chunkSize, int slotSize>
  142 int Chunk<chunkSize, slotSize>::getNumSlots (void)
  143 {
  144   return ((chunkSize - sizeof(Chunk)) / align (sizeof(ChunkBlock) + slotSize));
  145 }
  146 
  147 
  148 template <int chunkSize, int slotSize>
  149 int Chunk<chunkSize, slotSize>::getNumSlotsFree (void)
  150 {
  151   return numSlotsAvailable;
  152 }
  153 
  154 
  155 template <int chunkSize, int slotSize>
  156 int Chunk<chunkSize, slotSize>::getNumSlotsInUse (void)
  157 {
  158   return getNumSlots() - numSlotsAvailable;
  159 }
  160 
  161 
  162 template <int chunkSize, int slotSize>
  163 Chunk<chunkSize, slotSize> * Chunk<chunkSize, slotSize>::getChunk (void * ptr)
  164 {
  165   ChunkBlock * ch = getChunkBlock (ptr);
  166   return ch->getChunk();
  167 }
  168 
  169 };
  170 
  171 #endif