haiku/src/system/libroot/posix/malloc/threadheap.cpp
Axel Dörfler ac5af8f1b4 The maximum allocation size we've configured our allocator is 1 GB. Instead
of running into an assert() later on, we now back out early in this case.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@12902 a95241bf-73f2-0310-859d-f6bbb57e9c96
2005-05-30 14:10:06 +00:00

121 lines
3.0 KiB
C++

///-*-C++-*-//////////////////////////////////////////////////////////////////
//
// Hoard: A Fast, Scalable, and Memory-Efficient Allocator
// for Shared-Memory Multiprocessors
// 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.
//
//////////////////////////////////////////////////////////////////////////////
//#include <limits.h>
#include <string.h>
#include "config.h"
#include "heap.h"
#include "threadheap.h"
#include "processheap.h"
using namespace BPrivate;
threadHeap::threadHeap(void)
:_pHeap(0)
{
}
// malloc (sz):
// inputs: the size of the object to be allocated.
// returns: a pointer to an object of the appropriate size.
// side effects: allocates a block from a superblock;
// may call sbrk() (via makeSuperblock).
void *
threadHeap::malloc(const size_t size)
{
#if MAX_INTERNAL_FRAGMENTATION == 2
if (size > 1063315264UL) {
debug_printf("malloc() of %lu bytes asked\n", size);
return NULL;
}
#endif
const int sizeclass = sizeClass(size);
block *b = NULL;
lock();
// Look for a free block.
// We usually have memory locally so we first look for space in the
// superblock list.
superblock *sb = findAvailableSuperblock(sizeclass, b, _pHeap);
if (sb == NULL) {
// We don't have memory locally.
// Try to get more from the process heap.
assert(_pHeap);
sb = _pHeap->acquire((int)sizeclass, this);
// If we didn't get any memory from the process heap,
// we'll have to allocate our own superblock.
if (sb == NULL) {
sb = superblock::makeSuperblock(sizeclass, _pHeap);
if (sb == NULL) {
// We're out of memory!
unlock();
return NULL;
}
#if HEAP_LOG
// Record the memory allocation.
MemoryRequest m;
m.allocate((int)sb->getNumBlocks() *
(int)sizeFromClass(sb->getBlockSizeClass()));
_pHeap->getLog(getIndex()).append(m);
#endif
#if HEAP_FRAG_STATS
_pHeap->setAllocated(0,
sb->getNumBlocks() * sizeFromClass(sb->getBlockSizeClass()));
#endif
}
// Get a block from the superblock.
b = sb->getBlock();
assert(b != NULL);
// Insert the superblock into our list.
insertSuperblock(sizeclass, sb, _pHeap);
}
assert(b != NULL);
assert(b->isValid());
assert(sb->isValid());
b->markAllocated();
#if HEAP_LOG
MemoryRequest m;
m.malloc((void *)(b + 1), align(size));
_pHeap->getLog(getIndex()).append(m);
#endif
#if HEAP_FRAG_STATS
b->setRequestedSize(align(size));
_pHeap->setAllocated(align(size), 0);
#endif
unlock();
// Skip past the block header and return the pointer.
return (void *)(b + 1);
}