00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 #include <new>
00036 #include <string.h>
00037 
00038 #include "arch-specific.h"
00039 #include "config.h"
00040 #include "hoardheap.h"
00041 #include "processheap.h"
00042 #include "superblock.h"
00043 
00044 
00045 superblock::superblock (int numBlocks,  
00046                         int szclass,    
00047                         hoardHeap * o)  
00048   :
00049 #if HEAP_DEBUG
00050     _magic (SUPERBLOCK_MAGIC),
00051 #endif
00052     _sizeClass (szclass),
00053     _numBlocks (numBlocks),
00054     _numAvailable (0),
00055     _fullness (0),
00056     _freeList (NULL),
00057     _owner (o),
00058     _next (NULL),
00059     _prev (NULL),
00060     dirtyFullness (true)
00061 {
00062   assert (_numBlocks >= 1);
00063 
00064   
00065   const int blksize =
00066     hoardHeap::align (sizeof(block) + hoardHeap::sizeFromClass(_sizeClass));
00067 
00068   
00069   assert ((blksize & hoardHeap::ALIGNMENT_MASK) == 0);
00070 
00071   
00072   block * b
00073     = (block *) hoardHeap::align ((unsigned long) (this + 1));
00074 
00075   
00076   
00077   for (int i = 0; i < _numBlocks; i++) {
00078     
00079     assert (((unsigned int) b & hoardHeap::ALIGNMENT_MASK) == 0);
00080     new (b) block (this);
00081     assert (b->getSuperblock() == this);
00082     b->setNext (_freeList);
00083     _freeList = b;
00084     b = (block *) ((char *) b + blksize);
00085   }
00086   _numAvailable = _numBlocks;
00087   
00088   assert ((unsigned long) b <= hoardHeap::align (sizeof(superblock) + blksize * _numBlocks) + (unsigned long) this);
00089 
00090   hoardLockInit (_upLock);
00091 }
00092 
00093 
00094 superblock * superblock::makeSuperblock (int sizeclass,
00095                                          processHeap * pHeap)
00096 {
00097   
00098 
00099   char * buf;
00100   int numBlocks = hoardHeap::numBlocks(sizeclass);
00101 
00102   
00103   unsigned long moreMemory;
00104   size_t sz = hoardHeap::sizeFromClass(sizeclass);
00105 
00106   if (numBlocks > 1) {
00107         
00108 
00109     moreMemory = hoardHeap::SUPERBLOCK_SIZE;
00110     assert (moreMemory >= hoardHeap::align(sizeof(superblock) + (hoardHeap::align (sizeof(block) + sz)) * numBlocks));
00111 
00112     
00113     buf = (char *) hoardGetMemory (moreMemory);
00114 
00115   } else {
00116     
00117     assert (numBlocks == 1);
00118 
00119     size_t blksize = hoardHeap::align (sizeof(block) + sz);
00120     moreMemory = hoardHeap::align (sizeof(superblock) + blksize);
00121 
00122     
00123     buf = (char *) hoardGetMemory (moreMemory);
00124   }
00125  
00126   
00127   if (buf == NULL) {
00128     return 0;
00129   }
00130   buf = (char *) hoardHeap::align ((unsigned long) buf);
00131 
00132   
00133   assert (buf == (char *) hoardHeap::align ((unsigned long) buf));
00134   assert ((((unsigned long) buf) & hoardHeap::ALIGNMENT_MASK) == 0);
00135 
00136   
00137   superblock * sb = new (buf) superblock (numBlocks, sizeclass, NULL);
00138 
00139   return sb;
00140 }