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 <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,  
00048                         int szclass,    
00049                         hoardHeap * o,  
00050                         persistentSuperblock *psb) 
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         
00069         
00070         const int blksize =  hoardHeap::align (sizeof(block));
00071 
00072         
00073         assert ((blksize & hoardHeap::ALIGNMENT_MASK) == 0);
00074 
00075         
00076         block * b = (block *) hoardHeap::align ((unsigned long) (this + 1));
00077 
00078         _psb = psb;
00079         
00080         
00081         for (int i = 0; i < _numBlocks; i++) {
00082                 
00083                 assert (((uintptr_t) b & hoardHeap::ALIGNMENT_MASK) == 0);
00084                 new (b) block (this);
00085                 assert (b->getSuperblock() == this);
00086                 b->setId (i);
00087                 if (psb->isBlockFree(i)) {
00088                         b->setNext (_freeList);
00089                         _freeList = b;
00090                         _numAvailable++;
00091                 }
00092                 b = (block *) ((char *) b + blksize);
00093         }
00094         computeFullness();
00095         assert ((uintptr_t) b <= hoardHeap::align (sizeof(superblock) + blksize * _numBlocks) + (uintptr_t) this);
00096 
00097         hoardLockInit (_upLock);
00098 }
00099 
00100 
00101 superblock * superblock::makeSuperblock (int sizeclass,
00102                                          persistentSuperblock *pSuperblock)
00103 {
00104         char *buf;
00105         int  numBlocks = hoardHeap::numBlocks(sizeclass);
00106         int  blksize = hoardHeap::sizeFromClass(sizeclass);
00107   
00108         
00109         unsigned long moreMemory;
00110 
00111         moreMemory = hoardHeap::align(sizeof(superblock) + (hoardHeap::align (sizeof(block)) * numBlocks));
00112         
00113         buf = (char *) hoardGetMemory (moreMemory);
00114  
00115         
00116         if (buf == NULL) {
00117                 return 0;
00118         }
00119         buf = (char *) hoardHeap::align ((unsigned long) buf);
00120 
00121         
00122         assert (buf == (char *) hoardHeap::align ((unsigned long) buf));
00123         assert ((((unsigned long) buf) & hoardHeap::ALIGNMENT_MASK) == 0);
00124 
00125         
00126         
00127         if (pSuperblock->getBlockSize() != blksize) {
00128                 assert(pSuperblock->isFree() == true);
00129                 pSuperblock->setBlockSize(blksize);
00130         }
00131 
00132         
00133 
00134         superblock * sb = new (buf) superblock (numBlocks, sizeclass, NULL, pSuperblock);
00135         pSuperblock->setSuperblock(sb);
00136 
00137         return sb;
00138 }
00139 
00140 
00141 superblock * superblock::makeSuperblock (persistentSuperblock *pSuperblock)
00142 {
00143         
00144 
00145         int  blksize = pSuperblock->getBlockSize();
00146         int  sizeclass = hoardHeap::sizeClass(blksize);
00147 
00148         return makeSuperblock(sizeclass, pSuperblock);
00149 }
00150 
00151 
00152 block *superblock::getBlock (int id)
00153 {
00154         block * b = (block *) hoardHeap::align ((unsigned long) (this + 1));
00155         const int blksize = hoardHeap::align (sizeof(block));
00156   
00157         b = (block *) ((char *) b + id*blksize);
00158         return b;
00159 }