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
00077 = (block *) hoardHeap::align ((unsigned long) (this + 1));
00078
00079 _psb = psb;
00080
00081
00082 for (int i = 0; i < _numBlocks; i++) {
00083
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
00107
00108 char * buf;
00109 int numBlocks = hoardHeap::numBlocks(sizeclass);
00110 persistentSuperblock * pSuperblock;
00111
00112
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
00119 buf = (char *) hoardGetMemory (moreMemory);
00120 pSuperblock = persistentheap->acquirePersistentSuperblock(true, 0, sz);
00121 } else {
00122
00123
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
00131 buf = (char *) hoardGetMemory (moreMemory);
00132 }
00133
00134
00135 if (buf == NULL) {
00136 return 0;
00137 }
00138 buf = (char *) hoardHeap::align ((unsigned long) buf);
00139
00140
00141 assert (buf == (char *) hoardHeap::align ((unsigned long) buf));
00142 assert ((((unsigned long) buf) & hoardHeap::ALIGNMENT_MASK) == 0);
00143
00144
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
00160 unsigned long moreMemory;
00161
00162 moreMemory = hoardHeap::align(sizeof(superblock) + (hoardHeap::align (sizeof(block)) * numBlocks));
00163
00164 buf = (char *) hoardGetMemory (moreMemory);
00165
00166
00167 if (buf == NULL) {
00168 return 0;
00169 }
00170 buf = (char *) hoardHeap::align ((unsigned long) buf);
00171
00172
00173 assert (buf == (char *) hoardHeap::align ((unsigned long) buf));
00174 assert ((((unsigned long) buf) & hoardHeap::ALIGNMENT_MASK) == 0);
00175
00176
00177
00178 if (pSuperblock->getBlockSize() != blksize) {
00179 assert(pSuperblock->isFree() == true);
00180 pSuperblock->setBlockSize(blksize);
00181 }
00182
00183
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
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