usermode/library/malloc-hoard-old/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 "arch-specific.h"
00041 #include "block.h"
00042 #include "persistentsuperblock.h"
00043 
00044 class hoardHeap;            // forward declaration
00045 class processHeap;          // forward declaration
00046 class persistentHeap;       // forward declaration
00047 
00048 class superblock {
00049 
00050 public:
00051 
00052   // Construct a superblock for a given size class and set the heap
00053   // owner.
00054   superblock (int numblocks,
00055               int sizeclass,
00056               hoardHeap * owner,
00057           persistentSuperblock *psb);
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, persistentHeap *persistentHeap);
00066   static superblock * makeSuperblock (int sizeclass, persistentSuperblock *pSuperblock);
00067   static superblock * makeSuperblock (persistentSuperblock *pSuperblock);
00068 
00069   // Find out who allocated this superblock.
00070   inline hoardHeap * getOwner (void);
00071 
00072   // Set the superblock's owner.
00073   inline void setOwner (hoardHeap * o);
00074 
00075   // Get (allocate) a block from the superblock.
00076   inline block * acquireBlock (void);
00077 
00078   // Put a block back in the superblock.
00079   inline void putBlock (block * b);
00080 
00081   // Get a pointer to the block identified by id.
00082   block * getBlock (int id);
00083 
00084   // How many blocks are available?
00085   inline int getNumAvailable (void);
00086 
00087   // How many blocks are there, in total?
00088   inline int getNumBlocks (void);
00089 
00090   // What size class are blocks in this superblock?
00091   inline int getBlockSizeClass (void);
00092 
00093   // Insert this superblock before the next one.
00094   inline void insertBefore (superblock * nextSb);
00095 
00096   // Return the next pointer (to the next superblock in the list).
00097   inline superblock * getNext (void);
00098 
00099   // Return the prev pointer (to the previous superblock in the list).
00100   inline superblock * getPrev (void);
00101 
00102   // Return the 'fullness' of this superblock.
00103   inline int getFullness (void);
00104   
00105 #if HEAP_FRAG_STATS
00106   // Return the amount of waste in every allocated block.
00107   int getMaxInternalFragmentation (void);
00108 #endif
00109 
00110   // Remove this superblock from its linked list.
00111   inline void remove (void);
00112 
00113   // Is this superblock valid? (i.e.,
00114   // does it have the right magic number?)
00115   inline int isValid (void);
00116 
00117   inline void upLock (void) {
00118     hoardLock (_upLock);
00119   }
00120 
00121   inline void upUnlock (void) {
00122     hoardUnlock (_upLock);
00123   }
00124 
00125   // Compute the 'fullness' of this superblock.
00126   inline void computeFullness (void);
00127 
00128   inline persistentSuperblock *getPersistentSuperblock(void);
00129   inline void *getBlockRegion(int id);
00130 private:
00131 
00132 
00133   // Disable copying and assignment.
00134 
00135   superblock (const superblock&);
00136   const superblock& operator= (const superblock&);
00137 
00138   // Used for sanity checking.
00139   enum { SUPERBLOCK_MAGIC = 0xCAFEBABE };
00140 
00141 #if HEAP_DEBUG
00142   unsigned long _magic;
00143 #endif
00144 
00145   const int     _sizeClass;     // The size class of blocks in the superblock.
00146   const int     _numBlocks;     // The number of blocks in the superblock.
00147   int           _numAvailable;  // The number of blocks available.
00148   int           _fullness;      // How full is this superblock?
00149                                 // (which SUPERBLOCK_FULLNESS group is it in)
00150   block *       _freeList;      // A pointer to the first free block.
00151   hoardHeap *   _owner;         // The heap who owns this superblock.
00152   superblock *  _next;          // The next superblock in the list.
00153   superblock *  _prev;          // The previous superblock in the list.
00154 
00155   persistentSuperblock *_psb; // The persistent superblock backing this volatile superblock header.
00156   bool dirtyFullness;
00157 
00158   hoardLockType _upLock;        // Lock this when moving a superblock to the global (process) heap.
00159 
00160   // We insert a cache pad here to prevent false sharing with the
00161   // first block (which immediately follows the superblock).
00162 
00163   double _pad[CACHE_LINE / sizeof(double)];
00164 };
00165 
00166 
00167 hoardHeap * superblock::getOwner (void)
00168 {
00169   assert (isValid());
00170   hoardHeap * o = _owner;
00171   return o;
00172 }
00173 
00174 
00175 void superblock::setOwner (hoardHeap * o) 
00176 {
00177   assert (isValid());
00178   _owner = o;
00179 }
00180 
00181 
00182 block * superblock::acquireBlock (void)
00183 {
00184   assert (isValid());
00185   // Pop off a block from this superblock's freelist,
00186   // if there is one available.
00187   if (_freeList == NULL) {
00188     // The freelist is empty.
00189     assert (getNumAvailable() == 0);
00190     return NULL;
00191   }
00192   assert (getNumAvailable() > 0);
00193   block * b = _freeList;
00194   _freeList = _freeList->getNext();
00195   _numAvailable--;
00196   _psb->allocBlock(b->getId());
00197 
00198   b->setNext(NULL);
00199 
00200   dirtyFullness = true;
00201   //  computeFullness();
00202 
00203   return b;
00204 }
00205 
00206 
00207 void superblock::putBlock (block * b)
00208 {
00209   assert (isValid());
00210   // Push a block onto the superblock's freelist.
00211   assert (b->isValid());
00212   assert (b->getSuperblock() == this);
00213   assert (getNumAvailable() < getNumBlocks());
00214   b->setNext (_freeList);
00215   _freeList = b;
00216   _numAvailable++;
00217   _psb->freeBlock(b->getId());
00218 
00219   dirtyFullness = true;
00220   //  computeFullness();
00221 }
00222 
00223 
00224 
00225 int superblock::getNumAvailable (void)
00226 {
00227   assert (isValid());
00228   return _numAvailable;
00229 }
00230 
00231 
00232 int superblock::getNumBlocks (void)
00233 {
00234   assert (isValid());
00235   return _numBlocks;
00236 }
00237 
00238 
00239 int superblock::getBlockSizeClass (void)
00240 {
00241   assert (isValid());
00242   return _sizeClass;
00243 }
00244 
00245 
00246 superblock * superblock::getNext (void)
00247 {
00248   assert (isValid());
00249   return _next; 
00250 }
00251 
00252 superblock * superblock::getPrev (void)
00253 {
00254   assert (isValid());
00255   return _prev; 
00256 }
00257 
00258 
00259 void superblock::insertBefore (superblock * nextSb) {
00260   assert (isValid());
00261   // Insert this superblock before the next one (nextSb).
00262   assert (nextSb != this);
00263   _next = nextSb;
00264   if (nextSb) {
00265     _prev = nextSb->_prev;
00266     nextSb->_prev = this;
00267   }
00268 }
00269 
00270 
00271 void superblock::remove (void) {
00272   // Remove this superblock from a doubly-linked list.
00273   if (_next) {
00274     _next->_prev = _prev;
00275   }
00276   if (_prev) {
00277     _prev->_next = _next;
00278   }
00279   _prev = NULL;
00280   _next = NULL;
00281 }
00282 
00283 
00284 int superblock::isValid (void)
00285 {
00286   assert (_numBlocks > 0);
00287   assert (_numAvailable <= _numBlocks);
00288   assert (_sizeClass >= 0);
00289   return 1;
00290 }
00291 
00292 
00293 void superblock::computeFullness (void)
00294 {
00295   assert (isValid());
00296   _fullness = (((SUPERBLOCK_FULLNESS_GROUP - 1)
00297                 * (getNumBlocks() - getNumAvailable())) / getNumBlocks());
00298 }
00299 
00300 int superblock::getFullness (void)
00301 {
00302   assert (isValid());
00303   if (dirtyFullness) {
00304     computeFullness();
00305     dirtyFullness = false;
00306   }
00307   return _fullness;
00308 }
00309 
00310 persistentSuperblock *superblock::getPersistentSuperblock(void)
00311 {
00312         return _psb;
00313 }
00314 
00315 void *superblock::getBlockRegion(int id)
00316 {
00317         return _psb->getBlockRegion(id);
00318 }
00319 
00320 
00321 #endif // _SUPERBLOCK_H_

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