usermode/library/malloc-hoard-old/src/superblock.cpp

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.cpp
00023   ------------------------------------------------------------------------
00024   The superblock class controls a number of blocks (which are
00025   allocatable units of memory).
00026   ------------------------------------------------------------------------
00027   @(#) $Id: superblock.cpp,v 1.45 2001/12/18 02:42:56 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 #include <string.h>
00036 
00037 #include "arch-specific.h"
00038 #include "config.h"
00039 #include "hoardheap.h"
00040 #include "superblock.h"
00041 #include "persistentheap.h"
00042 #include "persistentsuperblock.h"
00043 
00044 #include <iostream>
00045 using namespace std;
00046 
00047 superblock::superblock (int numBlocks,  // The number of blocks in the sb.
00048                         int szclass,    // The size class of the blocks.
00049                         hoardHeap * o,  // The heap that "owns" this sb.
00050                         persistentSuperblock *psb) // The persistent sb backing this volatile sb
00051                         :
00052 #if HEAP_DEBUG
00053     _magic (SUPERBLOCK_MAGIC),
00054 #endif
00055     _sizeClass (szclass),
00056     _numBlocks (numBlocks),
00057     _numAvailable (0),
00058     _fullness (0),
00059     _freeList (NULL),
00060     _owner (o),
00061     _next (NULL),
00062     _prev (NULL),
00063     dirtyFullness (true)
00064 {
00065   assert (_numBlocks >= 1);
00066 
00067 
00068   // Determine the size of each block. This does not include the buffer 
00069   // since the block is actually a cached header for the 
00070   const int blksize =  hoardHeap::align (sizeof(block));
00071 
00072   // Make sure this size is in fact aligned.
00073   assert ((blksize & hoardHeap::ALIGNMENT_MASK) == 0);
00074 
00075   // Set the first block to just past this volatile superblock header.
00076   block * b
00077     = (block *) hoardHeap::align ((unsigned long) (this + 1));
00078 
00079   _psb = psb;
00080   // Initialize all the blocks,
00081   // and insert the block pointers into the linked list.
00082   for (int i = 0; i < _numBlocks; i++) {
00083     // Make sure the block is on a double-word boundary.
00084     assert (((uintptr_t) b & hoardHeap::ALIGNMENT_MASK) == 0);
00085     new (b) block (this);
00086     assert (b->getSuperblock() == this);
00087         b->setId (i);
00088         if (psb->isBlockFree(i)) {
00089         b->setNext (_freeList);
00090             _freeList = b;
00091                 _numAvailable++;
00092         }
00093     b = (block *) ((char *) b + blksize);
00094   }
00095   computeFullness();
00096   assert ((uintptr_t) b <= hoardHeap::align (sizeof(superblock) + blksize * _numBlocks) + (uintptr_t) this);
00097 
00098   hoardLockInit (_upLock);
00099 }
00100 
00101 
00102 
00103 superblock * superblock::makeSuperblock (int sizeclass,
00104                                          processHeap * , persistentHeap *persistentheap)
00105 {
00106   // We need to get more memory.
00107 
00108   char * buf;
00109   int numBlocks = hoardHeap::numBlocks(sizeclass);
00110   persistentSuperblock * pSuperblock;
00111   
00112   // Compute how much memory we need.
00113   unsigned long moreMemory;
00114   size_t sz = hoardHeap::sizeFromClass(sizeclass);
00115 
00116   if (numBlocks > 1) {
00117     moreMemory = hoardHeap::align(sizeof(superblock) + (hoardHeap::align (sizeof(block)) * numBlocks));
00118     // Get some memory from the process heap.
00119     buf = (char *) hoardGetMemory (moreMemory);
00120         pSuperblock = persistentheap->acquirePersistentSuperblock(true, 0, sz);
00121   } else {
00122     // One object.
00123         // TODO: non-fixed size persistent supeblock
00124         assert (0);
00125     assert (numBlocks == 1);
00126 
00127     size_t blksize = hoardHeap::align (sizeof(block) + sz);
00128     moreMemory = hoardHeap::align (sizeof(superblock) + blksize);
00129 
00130     // Get space from the system.
00131     buf = (char *) hoardGetMemory (moreMemory);
00132   }
00133  
00134   // Make sure that we actually got the memory.
00135   if (buf == NULL) {
00136     return 0;
00137   }
00138   buf = (char *) hoardHeap::align ((unsigned long) buf);
00139 
00140   // Make sure this buffer is double-word aligned.
00141   assert (buf == (char *) hoardHeap::align ((unsigned long) buf));
00142   assert ((((unsigned long) buf) & hoardHeap::ALIGNMENT_MASK) == 0);
00143 
00144   // Instantiate the new superblock in the buffer.
00145 
00146   superblock * sb = new (buf) superblock (numBlocks, sizeclass, NULL, pSuperblock);
00147 
00148   return sb;
00149 }
00150 
00151 
00152 superblock * superblock::makeSuperblock (int sizeclass,
00153                                          persistentSuperblock *pSuperblock)
00154 {
00155   char *buf;
00156   int  numBlocks = hoardHeap::numBlocks(sizeclass);
00157   int  blksize = hoardHeap::sizeFromClass(sizeclass);
00158   
00159   // Compute how much memory we need.
00160   unsigned long moreMemory;
00161 
00162   moreMemory = hoardHeap::align(sizeof(superblock) + (hoardHeap::align (sizeof(block)) * numBlocks));
00163   // Get some memory from the process heap.
00164   buf = (char *) hoardGetMemory (moreMemory);
00165  
00166   // Make sure that we actually got the memory.
00167   if (buf == NULL) {
00168     return 0;
00169   }
00170   buf = (char *) hoardHeap::align ((unsigned long) buf);
00171 
00172   // Make sure this buffer is double-word aligned.
00173   assert (buf == (char *) hoardHeap::align ((unsigned long) buf));
00174   assert ((((unsigned long) buf) & hoardHeap::ALIGNMENT_MASK) == 0);
00175 
00176   // If sizeclass is different from the pSuperblock's sizeclass then make
00177   // sure that the pSuperblock is free
00178   if (pSuperblock->getBlockSize() != blksize) {
00179     assert(pSuperblock->isFree() == true);
00180         pSuperblock->setBlockSize(blksize);
00181   }
00182 
00183   // Instantiate the new superblock in the buffer.
00184 
00185   superblock * sb = new (buf) superblock (numBlocks, sizeclass, NULL, pSuperblock);
00186   pSuperblock->setSuperblock(sb);
00187 
00188   return sb;
00189 }
00190 
00191 
00192 superblock * superblock::makeSuperblock (persistentSuperblock *pSuperblock)
00193 {
00194   // We need to get more memory.
00195 
00196   int  blksize = pSuperblock->getBlockSize();
00197   int  sizeclass = hoardHeap::sizeClass(blksize);
00198 
00199   return makeSuperblock(sizeclass, pSuperblock);
00200 }
00201 
00202 block *superblock::getBlock (int id)
00203 {
00204   block * b = (block *) hoardHeap::align ((unsigned long) (this + 1));
00205   const int blksize = hoardHeap::align (sizeof(block));
00206   
00207   b = (block *) ((char *) b + id*blksize);
00208   return b;
00209 }
00210 
00211 

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