superblock.cpp
------------------------------------------------------------------------
The superblock class controls a number of blocks (which are
allocatable units of memory).
------------------------------------------------------------------------
Emery Berger | <http://www.cs.utexas.edu/users/emery>
Department of Computer Sciences | <http://www.cs.utexas.edu>
University of Texas at Austin | <http://www.utexas.edu>
========================================================================
*/
#include <string.h>
#include "arch-specific.h"
#include "config.h"
#include "heap.h"
#include "processheap.h"
#include "superblock.h"
using namespace BPrivate;
superblock::superblock(int numBlocks,
int szclass,
hoardHeap * o)
:
#if HEAP_DEBUG
_magic(SUPERBLOCK_MAGIC),
#endif
_sizeClass(szclass),
_numBlocks(numBlocks),
_numAvailable(0),
_fullness(0), _freeList(NULL), _owner(o), _next(NULL), _prev(NULL)
{
assert(_numBlocks >= 1);
const int blksize = hoardHeap::align(sizeof(block)
+ hoardHeap::sizeFromClass(_sizeClass));
assert((blksize & hoardHeap::ALIGNMENT_MASK) == 0);
block *b = (block *) hoardHeap::align((unsigned long)(this + 1));
for (int i = 0; i < _numBlocks; i++) {
assert(((unsigned long)b & hoardHeap::ALIGNMENT_MASK) == 0);
new(b) block(this);
assert(b->getSuperblock() == this);
b->setNext(_freeList);
_freeList = b;
b = (block *)((char *)b + blksize);
}
_numAvailable = _numBlocks;
computeFullness();
assert((unsigned long)b <= hoardHeap::align(sizeof(superblock) + blksize * _numBlocks)
+ (unsigned long)this);
hoardLockInit(_upLock, "hoard superblock");
}
superblock *
superblock::makeSuperblock(int sizeclass, processHeap *pHeap)
{
char *buf;
int numBlocks = hoardHeap::numBlocks(sizeclass);
unsigned long moreMemory;
if (numBlocks > 1) {
moreMemory = hoardHeap::SUPERBLOCK_SIZE;
assert(moreMemory >= hoardHeap::align(sizeof(superblock)
+ (hoardHeap::align(sizeof(block)
+ hoardHeap::sizeFromClass(sizeclass))) * numBlocks));
buf = (char *)pHeap->getSuperblockBuffer();
} else {
assert(numBlocks == 1);
size_t blksize = hoardHeap::align(sizeof(block)
+ hoardHeap::sizeFromClass(sizeclass));
moreMemory = hoardHeap::align(sizeof(superblock) + blksize);
buf = (char *)hoardSbrk(moreMemory);
}
if (buf == NULL)
return 0;
buf = (char *)hoardHeap::align((unsigned long)buf);
assert(buf == (char *)hoardHeap::align((unsigned long)buf));
assert((((unsigned long)buf) & hoardHeap::ALIGNMENT_MASK) == 0);
return new(buf) superblock(numBlocks, sizeclass, NULL);
}