2002-10-05 17:13:32 +00:00
|
|
|
///-*-C++-*-//////////////////////////////////////////////////////////////////
|
|
|
|
|
//
|
|
|
|
|
// The Hoard Multiprocessor Memory Allocator
|
|
|
|
|
// Contact author: Emery Berger, http://www.cs.utexas.edu/users/emery
|
|
|
|
|
//
|
|
|
|
|
// Copyright (c) 1998-2000, The University of Texas at Austin.
|
|
|
|
|
//
|
|
|
|
|
// This library is free software; you can redistribute it and/or modify
|
|
|
|
|
// it under the terms of the GNU Library General Public License as
|
|
|
|
|
// published by the Free Software Foundation, http://www.fsf.org.
|
|
|
|
|
//
|
|
|
|
|
// This library is distributed in the hope that it will be useful, but
|
|
|
|
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
|
// Library General Public License for more details.
|
|
|
|
|
//
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
superblock.cpp
|
|
|
|
|
------------------------------------------------------------------------
|
|
|
|
|
The superblock class controls a number of blocks (which are
|
|
|
|
|
allocatable units of memory).
|
|
|
|
|
------------------------------------------------------------------------
|
2005-02-10 18:47:16 +00:00
|
|
|
@(#) $Id: superblock.cpp,v 1.2 2005/02/10 18:47:16 axeld Exp $
|
2002-10-05 17:13:32 +00:00
|
|
|
------------------------------------------------------------------------
|
|
|
|
|
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 <new.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
|
|
#include "arch-specific.h"
|
|
|
|
|
#include "config.h"
|
|
|
|
|
#include "heap.h"
|
|
|
|
|
#include "processheap.h"
|
|
|
|
|
#include "superblock.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
superblock::superblock (int numBlocks, // The number of blocks in the sb.
|
|
|
|
|
int szclass, // The size class of the blocks.
|
|
|
|
|
hoardHeap * o) // The heap that "owns" this sb.
|
|
|
|
|
:
|
|
|
|
|
#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);
|
|
|
|
|
|
|
|
|
|
// Determine the size of each block.
|
|
|
|
|
const int blksize =
|
|
|
|
|
hoardHeap::align (sizeof(block) + hoardHeap::sizeFromClass(_sizeClass));
|
|
|
|
|
|
|
|
|
|
// Make sure this size is in fact aligned.
|
|
|
|
|
assert ((blksize & hoardHeap::ALIGNMENT_MASK) == 0);
|
|
|
|
|
|
|
|
|
|
// Set the first block to just past this superblock header.
|
|
|
|
|
block * b
|
|
|
|
|
= (block *) hoardHeap::align ((unsigned long) (this + 1));
|
|
|
|
|
|
|
|
|
|
// Initialize all the blocks,
|
|
|
|
|
// and insert the block pointers into the linked list.
|
|
|
|
|
for (int i = 0; i < _numBlocks; i++) {
|
|
|
|
|
// Make sure the block is on a double-word boundary.
|
|
|
|
|
assert (((unsigned int) 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);
|
|
|
|
|
|
2005-02-10 18:47:16 +00:00
|
|
|
hoardLockInit(_upLock, "hoard superblock");
|
2002-10-05 17:13:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
superblock * superblock::makeSuperblock (int sizeclass,
|
|
|
|
|
processHeap * pHeap)
|
|
|
|
|
{
|
|
|
|
|
// We need to get more memory.
|
|
|
|
|
|
|
|
|
|
char * buf;
|
|
|
|
|
int numBlocks = hoardHeap::numBlocks(sizeclass);
|
|
|
|
|
|
|
|
|
|
// Compute how much memory we need.
|
|
|
|
|
unsigned long moreMemory;
|
|
|
|
|
if (numBlocks > 1) {
|
|
|
|
|
moreMemory = hoardHeap::SUPERBLOCK_SIZE;
|
|
|
|
|
assert (moreMemory >= hoardHeap::align(sizeof(superblock) + (hoardHeap::align (sizeof(block) + hoardHeap::sizeFromClass(sizeclass))) * numBlocks));
|
|
|
|
|
|
|
|
|
|
// Get some memory from the process heap.
|
|
|
|
|
buf = (char *) pHeap->getSuperblockBuffer();
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
// One object.
|
|
|
|
|
assert (numBlocks == 1);
|
|
|
|
|
|
|
|
|
|
size_t blksize = hoardHeap::align (sizeof(block) + hoardHeap::sizeFromClass(sizeclass));
|
|
|
|
|
moreMemory = hoardHeap::align (sizeof(superblock) + blksize);
|
|
|
|
|
|
|
|
|
|
// Get space from the system.
|
|
|
|
|
buf = (char *) hoardSbrk (moreMemory);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Make sure that we actually got the memory.
|
|
|
|
|
if (buf == NULL) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
buf = (char *) hoardHeap::align ((unsigned long) buf);
|
|
|
|
|
|
|
|
|
|
// Make sure this buffer is double-word aligned.
|
|
|
|
|
assert (buf == (char *) hoardHeap::align ((unsigned long) buf));
|
|
|
|
|
assert ((((unsigned long) buf) & hoardHeap::ALIGNMENT_MASK) == 0);
|
|
|
|
|
|
|
|
|
|
// Instantiate the new superblock in the buffer.
|
|
|
|
|
superblock * sb = new (buf) superblock (numBlocks, sizeclass, NULL);
|
|
|
|
|
|
|
|
|
|
return sb;
|
|
|
|
|
}
|