usermode/library/malloc-original/src/superblock.h

00001 
00002 //
00003 // The Hoard Multiprocessor Memory Allocator
00004 // www.hoard.org
00005 //
00006 // Author: Emery Berger, http://www.cs.utexas.edu/users/emery
00007 //
00008 // Copyright (c) 1998-2001, The University of Texas at Austin.
00009 //
00010 // This library is free software; you can redistribute it and/or modify
00011 // it under the terms of the GNU Library General Public License as
00012 // published by the Free Software Foundation, http://www.fsf.org.
00013 //
00014 // This library is distributed in the hope that it will be useful, but
00015 // WITHOUT ANY WARRANTY; without even the implied warranty of
00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017 // Library General Public License for more details.
00018 //
00020 
00021 /*
00022   superblock.h
00023   ------------------------------------------------------------------------
00024   The superblock class controls a number of blocks (which are
00025   allocatable units of memory).
00026   ------------------------------------------------------------------------
00027   @(#) $Id: superblock.h,v 1.41 2001/12/20 15:36:20 emery Exp $
00028   ------------------------------------------------------------------------
00029   Emery Berger                    | <http://www.cs.utexas.edu/users/emery>
00030   Department of Computer Sciences |             <http://www.cs.utexas.edu>
00031   University of Texas at Austin   |                <http://www.utexas.edu>
00032   ========================================================================
00033 */
00034 
00035 #ifndef _SUPERBLOCK_H_
00036 #define _SUPERBLOCK_H_
00037 
00038 #include "config.h"
00039 
00040 #include <new>
00041 //#include <stdio.h>
00042 
00043 #include "arch-specific.h"
00044 #include "block.h"
00045 
00046 class hoardHeap; // forward declaration
00047 class processHeap; // forward declaration
00048 
00049 class superblock {
00050 
00051 public:
00052 
00053   // Construct a superblock for a given size class and set the heap
00054   // owner.
00055   superblock (int numblocks,
00056               int sizeclass,
00057               hoardHeap * owner);
00058 
00059   ~superblock (void)
00060   {
00061           hoardLockDestroy (_upLock);
00062   }
00063 
00064   // Make (allocate or re-use) a superblock for a given size class.
00065   static superblock * makeSuperblock (int sizeclass, processHeap * pHeap);
00066 
00067   // Find out who allocated this superblock.
00068   inline hoardHeap * getOwner (void);
00069 
00070   // Set the superblock's owner.
00071   inline void setOwner (hoardHeap * o);
00072 
00073   // Get a block from the superblock.
00074   inline block * getBlock (void);
00075 
00076   // Put a block back in the superblock.
00077   inline void putBlock (block * b);
00078 
00079   // How many blocks are available?
00080   inline int getNumAvailable (void);
00081 
00082   // How many blocks are there, in total?
00083   inline int getNumBlocks (void);
00084 
00085   // What size class are blocks in this superblock?
00086   inline int getBlockSizeClass (void);
00087 
00088   // Insert this superblock before the next one.
00089   inline void insertBefore (superblock * nextSb);
00090 
00091   // Return the next pointer (to the next superblock in the list).
00092   inline superblock * const getNext (void);
00093 
00094   // Return the prev pointer (to the previous superblock in the list).
00095   inline superblock * const getPrev (void);
00096 
00097   // Return the 'fullness' of this superblock.
00098   inline int getFullness (void);
00099   
00100 #if HEAP_FRAG_STATS
00101   // Return the amount of waste in every allocated block.
00102   int getMaxInternalFragmentation (void);
00103 #endif
00104 
00105   // Remove this superblock from its linked list.
00106   inline void remove (void);
00107 
00108   // Is this superblock valid? (i.e.,
00109   // does it have the right magic number?)
00110   inline int isValid (void);
00111 
00112   inline void upLock (void) {
00113     hoardLock (_upLock);
00114   }
00115 
00116   inline void upUnlock (void) {
00117     hoardUnlock (_upLock);
00118   }
00119 
00120   // Compute the 'fullness' of this superblock.
00121   inline void computeFullness (void);
00122 
00123 private:
00124 
00125 
00126   // Disable copying and assignment.
00127 
00128   superblock (const superblock&);
00129   const superblock& operator= (const superblock&);
00130 
00131   // Used for sanity checking.
00132   enum { SUPERBLOCK_MAGIC = 0xCAFEBABE };
00133 
00134 #if HEAP_DEBUG
00135   unsigned long _magic;
00136 #endif
00137 
00138   const int     _sizeClass;     // The size class of blocks in the superblock.
00139   const int     _numBlocks;     // The number of blocks in the superblock.
00140   int           _numAvailable;  // The number of blocks available.
00141   int           _fullness;      // How full is this superblock?
00142                                 // (which SUPERBLOCK_FULLNESS group is it in)
00143   block *       _freeList;      // A pointer to the first free block.
00144   hoardHeap *   _owner;         // The heap who owns this superblock.
00145   superblock *  _next;          // The next superblock in the list.
00146   superblock *  _prev;          // The previous superblock in the list.
00147 
00148   bool dirtyFullness;
00149 
00150   hoardLockType _upLock;        // Lock this when moving a superblock to the global (process) heap.
00151 
00152   // We insert a cache pad here to prevent false sharing with the
00153   // first block (which immediately follows the superblock).
00154 
00155   double _pad[CACHE_LINE / sizeof(double)];
00156 };
00157 
00158 
00159 hoardHeap * superblock::getOwner (void)
00160 {
00161   assert (isValid());
00162   hoardHeap * o = _owner;
00163   return o;
00164 }
00165 
00166 
00167 void superblock::setOwner (hoardHeap * o) 
00168 {
00169   assert (isValid());
00170   _owner = o;
00171 }
00172 
00173 
00174 block * superblock::getBlock (void)
00175 {
00176   assert (isValid());
00177   // Pop off a block from this superblock's freelist,
00178   // if there is one available.
00179   if (_freeList == NULL) {
00180     // The freelist is empty.
00181     assert (getNumAvailable() == 0);
00182     return NULL;
00183   }
00184   assert (getNumAvailable() > 0);
00185   block * b = _freeList;
00186   _freeList = _freeList->getNext();
00187   _numAvailable--;
00188 
00189   b->setNext(NULL);
00190 
00191   dirtyFullness = true;
00192   //  computeFullness();
00193 
00194   return b;
00195 }
00196 
00197 
00198 void superblock::putBlock (block * b)
00199 {
00200   assert (isValid());
00201   // Push a block onto the superblock's freelist.
00202   assert (b->isValid());
00203   assert (b->getSuperblock() == this);
00204   assert (getNumAvailable() < getNumBlocks());
00205   b->setNext (_freeList);
00206   _freeList = b;
00207   _numAvailable++;
00208 
00209   dirtyFullness = true;
00210   //  computeFullness();
00211 }
00212 
00213 int superblock::getNumAvailable (void)
00214 {
00215   assert (isValid());
00216   return _numAvailable;
00217 }
00218 
00219 
00220 int superblock::getNumBlocks (void)
00221 {
00222   assert (isValid());
00223   return _numBlocks;
00224 }
00225 
00226 
00227 int superblock::getBlockSizeClass (void)
00228 {
00229   assert (isValid());
00230   return _sizeClass;
00231 }
00232 
00233 
00234 superblock * const superblock::getNext (void)
00235 {
00236   assert (isValid());
00237   return _next; 
00238 }
00239 
00240 superblock * const superblock::getPrev (void)
00241 {
00242   assert (isValid());
00243   return _prev; 
00244 }
00245 
00246 
00247 void superblock::insertBefore (superblock * nextSb) {
00248   assert (isValid());
00249   // Insert this superblock before the next one (nextSb).
00250   assert (nextSb != this);
00251   _next = nextSb;
00252   if (nextSb) {
00253     _prev = nextSb->_prev;
00254     nextSb->_prev = this;
00255   }
00256 }
00257 
00258 
00259 void superblock::remove (void) {
00260   // Remove this superblock from a doubly-linked list.
00261   if (_next) {
00262     _next->_prev = _prev;
00263   }
00264   if (_prev) {
00265     _prev->_next = _next;
00266   }
00267   _prev = NULL;
00268   _next = NULL;
00269 }
00270 
00271 
00272 int superblock::isValid (void)
00273 {
00274   assert (_numBlocks > 0);
00275   assert (_numAvailable <= _numBlocks);
00276   assert (_sizeClass >= 0);
00277   return 1;
00278 }
00279 
00280 
00281 void superblock::computeFullness (void)
00282 {
00283         assert (isValid());
00284         _fullness = (((SUPERBLOCK_FULLNESS_GROUP - 1)
00285                       * (getNumBlocks() - getNumAvailable())) / getNumBlocks());
00286 }
00287 
00288 int superblock::getFullness (void)
00289 {
00290   assert (isValid());
00291   if (dirtyFullness) {
00292     computeFullness();
00293     dirtyFullness = false;
00294   }
00295   return _fullness;
00296 }
00297 
00298 #endif // _SUPERBLOCK_H_

Generated on Sat Apr 23 11:43:35 2011 for Mnemosyne by  doxygen 1.4.7