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 }