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

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