Applied our coding style, but all clases into the BPrivate namespace.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@11953 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -33,6 +33,7 @@ extern "C" {
|
|||||||
#include <OS.h>
|
#include <OS.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
using namespace BPrivate;
|
||||||
|
|
||||||
static area_id heap_region = -1;
|
static area_id heap_region = -1;
|
||||||
static addr_t brk;
|
static addr_t brk;
|
||||||
|
|||||||
@@ -24,22 +24,24 @@
|
|||||||
|
|
||||||
//#include <assert.h>
|
//#include <assert.h>
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
class superblock;
|
class superblock;
|
||||||
|
|
||||||
class block {
|
class block {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
block(superblock * sb)
|
block(superblock * sb)
|
||||||
:
|
:
|
||||||
#if HEAP_DEBUG
|
#if HEAP_DEBUG
|
||||||
_magic(FREE_BLOCK_MAGIC),
|
_magic(FREE_BLOCK_MAGIC),
|
||||||
#endif
|
#endif
|
||||||
_next (NULL),
|
_next(NULL), _mySuperblock(sb)
|
||||||
_mySuperblock (sb)
|
{
|
||||||
{}
|
}
|
||||||
|
|
||||||
block& operator= (const block& b) {
|
block &
|
||||||
|
operator=(const block & b)
|
||||||
|
{
|
||||||
#if HEAP_DEBUG
|
#if HEAP_DEBUG
|
||||||
_magic = b._magic;
|
_magic = b._magic;
|
||||||
#endif
|
#endif
|
||||||
@@ -51,8 +53,10 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum { ALLOCATED_BLOCK_MAGIC = 0xcafecafe,
|
enum {
|
||||||
FREE_BLOCK_MAGIC = 0xbabebabe };
|
ALLOCATED_BLOCK_MAGIC = 0xcafecafe,
|
||||||
|
FREE_BLOCK_MAGIC = 0xbabebabe
|
||||||
|
};
|
||||||
|
|
||||||
// Mark this block as free.
|
// Mark this block as free.
|
||||||
inline void markFree(void);
|
inline void markFree(void);
|
||||||
@@ -68,26 +72,46 @@ public:
|
|||||||
inline superblock *getSuperblock(void);
|
inline superblock *getSuperblock(void);
|
||||||
|
|
||||||
#if HEAP_FRAG_STATS
|
#if HEAP_FRAG_STATS
|
||||||
void setRequestedSize (size_t s)
|
void
|
||||||
|
setRequestedSize(size_t s)
|
||||||
{
|
{
|
||||||
_requestedSize = s;
|
_requestedSize = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t getRequestedSize (void) { return _requestedSize; }
|
size_t
|
||||||
|
getRequestedSize(void)
|
||||||
|
{
|
||||||
|
return _requestedSize;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if USE_PRIVATE_HEAPS
|
#if USE_PRIVATE_HEAPS
|
||||||
void setActualSize (size_t s) { _actualSize = s; }
|
void
|
||||||
size_t getActualSize (void) { return _actualSize; }
|
setActualSize(size_t s)
|
||||||
#endif
|
{
|
||||||
|
_actualSize = s;
|
||||||
|
}
|
||||||
|
|
||||||
void setNext (block * b) { _next = b; }
|
size_t
|
||||||
block * getNext (void) { return _next; }
|
getActualSize(void)
|
||||||
|
{
|
||||||
|
return _actualSize;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
void
|
||||||
|
setNext(block * b)
|
||||||
|
{
|
||||||
|
_next = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
block *
|
||||||
|
getNext(void)
|
||||||
|
{
|
||||||
|
return _next;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
#if USE_PRIVATE_HEAPS
|
#if USE_PRIVATE_HEAPS
|
||||||
|
|
||||||
#if HEAP_DEBUG
|
#if HEAP_DEBUG
|
||||||
union {
|
union {
|
||||||
unsigned long _magic;
|
unsigned long _magic;
|
||||||
@@ -102,8 +126,6 @@ private:
|
|||||||
double _d2; // For alignment.
|
double _d2; // For alignment.
|
||||||
superblock *_mySuperblock; // A pointer to my superblock.
|
superblock *_mySuperblock; // A pointer to my superblock.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#else // ! USE_PRIVATE_HEAPS
|
#else // ! USE_PRIVATE_HEAPS
|
||||||
|
|
||||||
#if HEAP_DEBUG
|
#if HEAP_DEBUG
|
||||||
@@ -115,7 +137,6 @@ private:
|
|||||||
|
|
||||||
block *_next; // The next block in a linked-list of blocks.
|
block *_next; // The next block in a linked-list of blocks.
|
||||||
superblock *_mySuperblock; // A pointer to my superblock.
|
superblock *_mySuperblock; // A pointer to my superblock.
|
||||||
|
|
||||||
#endif // USE_PRIVATE_HEAPS
|
#endif // USE_PRIVATE_HEAPS
|
||||||
|
|
||||||
#if HEAP_FRAG_STATS
|
#if HEAP_FRAG_STATS
|
||||||
@@ -126,21 +147,23 @@ private:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Disable copying.
|
// Disable copying.
|
||||||
|
|
||||||
block(const block &);
|
block(const block &);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
superblock * block::getSuperblock (void)
|
superblock *
|
||||||
|
block::getSuperblock(void)
|
||||||
{
|
{
|
||||||
#if HEAP_DEBUG
|
#if HEAP_DEBUG
|
||||||
assert(isValid());
|
assert(isValid());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return _mySuperblock;
|
return _mySuperblock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void block::markFree (void)
|
void
|
||||||
|
block::markFree(void)
|
||||||
{
|
{
|
||||||
#if HEAP_DEBUG
|
#if HEAP_DEBUG
|
||||||
assert(_magic == ALLOCATED_BLOCK_MAGIC);
|
assert(_magic == ALLOCATED_BLOCK_MAGIC);
|
||||||
@@ -149,7 +172,8 @@ void block::markFree (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void block::markAllocated (void)
|
void
|
||||||
|
block::markAllocated(void)
|
||||||
{
|
{
|
||||||
#if HEAP_DEBUG
|
#if HEAP_DEBUG
|
||||||
assert(_magic == FREE_BLOCK_MAGIC);
|
assert(_magic == FREE_BLOCK_MAGIC);
|
||||||
@@ -158,14 +182,17 @@ void block::markAllocated (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const int block::isValid (void) const
|
const int
|
||||||
|
block::isValid(void) const
|
||||||
{
|
{
|
||||||
#if HEAP_DEBUG
|
#if HEAP_DEBUG
|
||||||
return ((_magic == FREE_BLOCK_MAGIC)
|
return _magic == FREE_BLOCK_MAGIC
|
||||||
|| (_magic == ALLOCATED_BLOCK_MAGIC));
|
|| _magic == ALLOCATED_BLOCK_MAGIC;
|
||||||
#else
|
#else
|
||||||
return 1;
|
return 1;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
#endif // _BLOCK_H_
|
#endif // _BLOCK_H_
|
||||||
|
|||||||
@@ -89,4 +89,3 @@ enum { SUPERBLOCK_FULLNESS_GROUP = 9 };
|
|||||||
|
|
||||||
|
|
||||||
#endif // _CONFIG_H_
|
#endif // _CONFIG_H_
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
// Library General Public License for more details.
|
// Library General Public License for more details.
|
||||||
//
|
//
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include "heap.h"
|
#include "heap.h"
|
||||||
@@ -23,7 +24,7 @@
|
|||||||
#include "processheap.h"
|
#include "processheap.h"
|
||||||
#include "superblock.h"
|
#include "superblock.h"
|
||||||
|
|
||||||
static const char version[] = "The Hoard memory allocator, version 2.0 (http://www.hoard.org). Copyright (C) 1998, 1999, 2000 The University of Texas at Austin. $Id: heap.cpp,v 1.2 2005/02/10 18:47:16 axeld Exp $";
|
using namespace BPrivate;
|
||||||
|
|
||||||
// NB: Use maketable.cpp to update this
|
// NB: Use maketable.cpp to update this
|
||||||
// if SIZE_CLASSES, ALIGNMENT, SIZE_CLASS_BASE, MAX_EMPTY_SUPERBLOCKS,
|
// if SIZE_CLASSES, ALIGNMENT, SIZE_CLASS_BASE, MAX_EMPTY_SUPERBLOCKS,
|
||||||
@@ -31,21 +32,68 @@ static const char version[] = "The Hoard memory allocator, version 2.0 (http://w
|
|||||||
|
|
||||||
#if (MAX_INTERNAL_FRAGMENTATION == 2)
|
#if (MAX_INTERNAL_FRAGMENTATION == 2)
|
||||||
|
|
||||||
size_t hoardHeap::_sizeTable[hoardHeap::SIZE_CLASSES] = {8UL, 16UL, 24UL, 32UL, 40UL, 48UL, 56UL, 72UL, 80UL, 96UL, 120UL, 144UL, 168UL, 200UL, 240UL, 288UL, 344UL, 416UL, 496UL, 592UL, 712UL, 856UL, 1024UL, 1232UL, 1472UL, 1768UL, 2120UL, 2544UL, 3048UL, 3664UL, 4392UL, 5272UL, 6320UL, 7584UL, 9104UL, 10928UL, 13112UL, 15728UL, 18872UL, 22648UL, 27176UL, 32616UL, 39136UL, 46960UL, 56352UL, 67624UL, 81144UL, 97376UL, 116848UL, 140216UL, 168256UL, 201904UL, 242288UL, 290744UL, 348896UL, 418672UL, 502408UL, 602888UL, 723464UL, 868152UL, 1041784UL, 1250136UL, 1500160UL, 1800192UL, 2160232UL, 2592280UL, 3110736UL, 3732880UL, 4479456UL, 5375344UL, 6450408UL, 7740496UL, 9288592UL, 11146312UL, 13375568UL, 16050680UL, 19260816UL, 23112984UL, 27735576UL, 33282688UL, 39939224UL, 47927072UL, 57512488UL, 69014984UL, 82817976UL, 99381576UL, 119257888UL, 143109472UL, 171731360UL, 206077632UL, 247293152UL, 296751776UL, 356102144UL, 427322560UL, 512787072UL, 615344512UL, 738413376UL, 886096064UL, 1063315264UL};
|
size_t hoardHeap::_sizeTable[hoardHeap::SIZE_CLASSES] = {
|
||||||
|
8UL, 16UL, 24UL, 32UL, 40UL, 48UL, 56UL, 72UL, 80UL, 96UL, 120UL, 144UL,
|
||||||
|
168UL, 200UL, 240UL, 288UL, 344UL, 416UL, 496UL, 592UL, 712UL, 856UL,
|
||||||
|
1024UL, 1232UL, 1472UL, 1768UL, 2120UL, 2544UL, 3048UL, 3664UL,
|
||||||
|
4392UL, 5272UL, 6320UL, 7584UL, 9104UL, 10928UL, 13112UL, 15728UL,
|
||||||
|
18872UL, 22648UL, 27176UL, 32616UL, 39136UL, 46960UL, 56352UL,
|
||||||
|
67624UL, 81144UL, 97376UL, 116848UL, 140216UL, 168256UL, 201904UL,
|
||||||
|
242288UL, 290744UL, 348896UL, 418672UL, 502408UL, 602888UL, 723464UL,
|
||||||
|
868152UL, 1041784UL, 1250136UL, 1500160UL, 1800192UL, 2160232UL,
|
||||||
|
2592280UL, 3110736UL, 3732880UL, 4479456UL, 5375344UL, 6450408UL,
|
||||||
|
7740496UL, 9288592UL, 11146312UL, 13375568UL, 16050680UL, 19260816UL,
|
||||||
|
23112984UL, 27735576UL, 33282688UL, 39939224UL, 47927072UL,
|
||||||
|
57512488UL, 69014984UL, 82817976UL, 99381576UL, 119257888UL,
|
||||||
|
143109472UL, 171731360UL, 206077632UL, 247293152UL, 296751776UL,
|
||||||
|
356102144UL, 427322560UL, 512787072UL, 615344512UL, 738413376UL,
|
||||||
|
886096064UL, 1063315264UL
|
||||||
|
};
|
||||||
|
|
||||||
size_t hoardHeap::_threshold[hoardHeap::SIZE_CLASSES] = {4096UL, 2048UL, 1364UL, 1024UL, 816UL, 680UL, 584UL, 452UL, 408UL, 340UL, 272UL, 224UL, 192UL, 160UL, 136UL, 112UL, 92UL, 76UL, 64UL, 52UL, 44UL, 36UL, 32UL, 24UL, 20UL, 16UL, 12UL, 12UL, 8UL, 8UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL};
|
size_t hoardHeap::_threshold[hoardHeap::SIZE_CLASSES] = {
|
||||||
|
4096UL, 2048UL, 1364UL, 1024UL, 816UL, 680UL, 584UL, 452UL, 408UL,
|
||||||
|
340UL, 272UL, 224UL, 192UL, 160UL, 136UL, 112UL, 92UL, 76UL, 64UL,
|
||||||
|
52UL, 44UL, 36UL, 32UL, 24UL, 20UL, 16UL, 12UL, 12UL, 8UL, 8UL, 4UL,
|
||||||
|
4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL,
|
||||||
|
4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL,
|
||||||
|
4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL,
|
||||||
|
4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL,
|
||||||
|
4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL
|
||||||
|
};
|
||||||
|
|
||||||
#elif (MAX_INTERNAL_FRAGMENTATION == 6)
|
#elif (MAX_INTERNAL_FRAGMENTATION == 6)
|
||||||
|
|
||||||
size_t hoardHeap::_sizeTable[hoardHeap::SIZE_CLASSES] = {8UL, 16UL, 24UL, 32UL, 48UL, 72UL, 112UL, 176UL, 288UL, 456UL, 728UL, 1160UL, 1848UL, 2952UL, 4728UL, 7560UL, 12096UL, 19344UL, 30952UL, 49520UL, 79232UL, 126768UL, 202832UL, 324520UL, 519232UL, 830768UL, 1329232UL, 2126768UL, 3402824UL, 5444520UL, 8711232UL, 13937968UL, 22300752UL, 35681200UL, 57089912UL, 91343856UL, 146150176UL, 233840256UL, 374144416UL, 598631040UL, 957809728UL, 1532495488UL};
|
size_t hoardHeap::_sizeTable[hoardHeap::SIZE_CLASSES] = {
|
||||||
|
8UL, 16UL, 24UL, 32UL, 48UL, 72UL, 112UL, 176UL, 288UL, 456UL, 728UL,
|
||||||
|
1160UL, 1848UL, 2952UL, 4728UL, 7560UL, 12096UL, 19344UL, 30952UL,
|
||||||
|
49520UL, 79232UL, 126768UL, 202832UL, 324520UL, 519232UL, 830768UL,
|
||||||
|
1329232UL, 2126768UL, 3402824UL, 5444520UL, 8711232UL, 13937968UL,
|
||||||
|
22300752UL, 35681200UL, 57089912UL, 91343856UL, 146150176UL,
|
||||||
|
233840256UL, 374144416UL, 598631040UL, 957809728UL, 1532495488UL
|
||||||
|
};
|
||||||
|
|
||||||
size_t hoardHeap::_threshold[hoardHeap::SIZE_CLASSES] = {4096UL, 2048UL, 1364UL, 1024UL, 680UL, 452UL, 292UL, 184UL, 112UL, 68UL, 44UL, 28UL, 16UL, 8UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL};
|
size_t hoardHeap::_threshold[hoardHeap::SIZE_CLASSES] = {
|
||||||
|
4096UL, 2048UL, 1364UL, 1024UL, 680UL, 452UL, 292UL, 184UL, 112UL, 68UL,
|
||||||
|
44UL, 28UL, 16UL, 8UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL,
|
||||||
|
4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL,
|
||||||
|
4UL, 4UL, 4UL, 4UL, 4UL
|
||||||
|
};
|
||||||
|
|
||||||
#elif (MAX_INTERNAL_FRAGMENTATION == 10)
|
#elif (MAX_INTERNAL_FRAGMENTATION == 10)
|
||||||
|
|
||||||
size_t hoardHeap::_sizeTable[hoardHeap::SIZE_CLASSES] = {8UL, 16UL, 32UL, 64UL, 128UL, 256UL, 512UL, 1024UL, 2048UL, 4096UL, 8192UL, 16384UL, 32768UL, 65536UL, 131072UL, 262144UL, 524288UL, 1048576UL, 2097152UL, 4194304UL, 8388608UL, 16777216UL, 33554432UL, 67108864UL, 134217728UL, 268435456UL, 536870912UL, 1073741824UL, 2147483648UL};
|
size_t hoardHeap::_sizeTable[hoardHeap::SIZE_CLASSES] = {
|
||||||
|
8UL, 16UL, 32UL, 64UL, 128UL, 256UL, 512UL, 1024UL, 2048UL, 4096UL,
|
||||||
|
8192UL, 16384UL, 32768UL, 65536UL, 131072UL, 262144UL, 524288UL,
|
||||||
|
1048576UL, 2097152UL, 4194304UL, 8388608UL, 16777216UL, 33554432UL,
|
||||||
|
67108864UL, 134217728UL, 268435456UL, 536870912UL, 1073741824UL,
|
||||||
|
2147483648UL
|
||||||
|
};
|
||||||
|
|
||||||
size_t hoardHeap::_threshold[hoardHeap::SIZE_CLASSES] = {4096UL, 2048UL, 1024UL, 512UL, 256UL, 128UL, 64UL, 32UL, 16UL, 8UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL};
|
size_t hoardHeap::_threshold[hoardHeap::SIZE_CLASSES] = {
|
||||||
|
4096UL, 2048UL, 1024UL, 512UL, 256UL, 128UL, 64UL, 32UL, 16UL, 8UL, 4UL,
|
||||||
|
4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL, 4UL,
|
||||||
|
4UL, 4UL, 4UL, 4UL
|
||||||
|
};
|
||||||
|
|
||||||
#else
|
#else
|
||||||
# error "Undefined size class base."
|
# error "Undefined size class base."
|
||||||
@@ -53,30 +101,31 @@ size_t hoardHeap::_threshold[hoardHeap::SIZE_CLASSES] = {4096UL, 2048UL, 1024UL,
|
|||||||
|
|
||||||
|
|
||||||
hoardHeap::hoardHeap(void)
|
hoardHeap::hoardHeap(void)
|
||||||
: _index (0),
|
:
|
||||||
_reusableSuperblocks (NULL),
|
_index(0), _reusableSuperblocks(NULL), _reusableSuperblocksCount(0)
|
||||||
_reusableSuperblocksCount (0)
|
|
||||||
#if HEAP_DEBUG
|
#if HEAP_DEBUG
|
||||||
, _magic(HEAP_MAGIC)
|
, _magic(HEAP_MAGIC)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
// Initialize the per-heap lock.
|
// Initialize the per-heap lock.
|
||||||
hoardLockInit(_lock, "hoard heap");
|
hoardLockInit(_lock, "hoard heap");
|
||||||
|
|
||||||
for (int i = 0; i < SUPERBLOCK_FULLNESS_GROUP; i++) {
|
for (int i = 0; i < SUPERBLOCK_FULLNESS_GROUP; i++) {
|
||||||
for (int j = 0; j < SIZE_CLASSES; j++) {
|
for (int j = 0; j < SIZE_CLASSES; j++) {
|
||||||
// Initialize all superblocks lists to empty.
|
// Initialize all superblocks lists to empty.
|
||||||
_superblocks[i][j] = NULL;
|
_superblocks[i][j] = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int k = 0; k < SIZE_CLASSES; k++) {
|
for (int k = 0; k < SIZE_CLASSES; k++) {
|
||||||
_leastEmptyBin[k] = 0;
|
_leastEmptyBin[k] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void hoardHeap::insertSuperblock (int sizeclass,
|
void
|
||||||
superblock * sb,
|
hoardHeap::insertSuperblock(int sizeclass,
|
||||||
processHeap * pHeap)
|
superblock *sb, processHeap *pHeap)
|
||||||
{
|
{
|
||||||
assert(sb->isValid());
|
assert(sb->isValid());
|
||||||
assert(sb->getBlockSizeClass() == sizeclass);
|
assert(sb->getBlockSizeClass() == sizeclass);
|
||||||
@@ -93,38 +142,38 @@ void hoardHeap::insertSuperblock (int sizeclass,
|
|||||||
int fullness = sb->getFullness();
|
int fullness = sb->getFullness();
|
||||||
|
|
||||||
// Update the stats.
|
// Update the stats.
|
||||||
incStats (sizeclass,
|
incStats(sizeclass, sb->getNumBlocks() - sb->getNumAvailable(),
|
||||||
sb->getNumBlocks() - sb->getNumAvailable(),
|
|
||||||
sb->getNumBlocks());
|
sb->getNumBlocks());
|
||||||
|
|
||||||
if ((fullness == 0) &&
|
if (fullness == 0
|
||||||
(sb->getNumBlocks() > 1) &&
|
&& sb->getNumBlocks() > 1
|
||||||
(sb->getNumBlocks() == sb->getNumAvailable())) {
|
&& sb->getNumBlocks() == sb->getNumAvailable()) {
|
||||||
// Recycle this superblock.
|
// Recycle this superblock.
|
||||||
#if 0
|
#if 0
|
||||||
removeSuperblock(sb, sizeclass);
|
removeSuperblock(sb, sizeclass);
|
||||||
// Update the stats.
|
// Update the stats.
|
||||||
decStats(sizeclass,
|
decStats(sizeclass,
|
||||||
sb->getNumBlocks() - sb->getNumAvailable(),
|
sb->getNumBlocks() - sb->getNumAvailable(), sb->getNumBlocks());
|
||||||
sb->getNumBlocks());
|
|
||||||
// Free it immediately.
|
// Free it immediately.
|
||||||
const size_t s = sizeFromClass(sizeclass);
|
const size_t s = sizeFromClass(sizeclass);
|
||||||
const int blksize = align(sizeof(block) + s);
|
const int blksize = align(sizeof(block) + s);
|
||||||
#if HEAP_LOG
|
#if HEAP_LOG
|
||||||
// Record the memory deallocation.
|
// Record the memory deallocation.
|
||||||
MemoryRequest m;
|
MemoryRequest m;
|
||||||
m.deallocate ((int) sb->getNumBlocks() * (int) sizeFromClass(sb->getBlockSizeClass()));
|
m.deallocate((int)sb->getNumBlocks() *
|
||||||
|
(int)sizeFromClass(sb->getBlockSizeClass()));
|
||||||
pHeap->getLog(getIndex()).append(m);
|
pHeap->getLog(getIndex()).append(m);
|
||||||
#endif
|
#endif
|
||||||
#if HEAP_FRAG_STATS
|
#if HEAP_FRAG_STATS
|
||||||
|
|
||||||
pHeap->setDeallocated(0, sb->getNumBlocks() * sizeFromClass(sb->getBlockSizeClass()));
|
pHeap->setDeallocated(0, sb->getNumBlocks() * sizeFromClass(sb->getBlockSizeClass()));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
hoardUnsbrk(sb, align(sizeof(superblock) + blksize));
|
hoardUnsbrk(sb, align(sizeof(superblock) + blksize));
|
||||||
#else
|
#else
|
||||||
recycle(sb);
|
recycle(sb);
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// Insert it into the appropriate list.
|
// Insert it into the appropriate list.
|
||||||
superblock *&head = _superblocks[fullness][sizeclass];
|
superblock *&head = _superblocks[fullness][sizeclass];
|
||||||
sb->insertBefore(head);
|
sb->insertBefore(head);
|
||||||
@@ -137,7 +186,8 @@ void hoardHeap::insertSuperblock (int sizeclass,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
superblock * hoardHeap::removeMaxSuperblock (int sizeclass)
|
superblock *
|
||||||
|
hoardHeap::removeMaxSuperblock(int sizeclass)
|
||||||
{
|
{
|
||||||
assert(_magic == HEAP_MAGIC);
|
assert(_magic == HEAP_MAGIC);
|
||||||
|
|
||||||
@@ -169,15 +219,14 @@ superblock * hoardHeap::removeMaxSuperblock (int sizeclass)
|
|||||||
// we never need to check it. But for robustness, we leave it in.
|
// we never need to check it. But for robustness, we leave it in.
|
||||||
while (i < SUPERBLOCK_FULLNESS_GROUP) {
|
while (i < SUPERBLOCK_FULLNESS_GROUP) {
|
||||||
head = _superblocks[i][sizeclass];
|
head = _superblocks[i][sizeclass];
|
||||||
if (head) {
|
if (head)
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!head) {
|
if (!head)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure that this superblock is at least 1/EMPTY_FRACTION
|
// Make sure that this superblock is at least 1/EMPTY_FRACTION
|
||||||
// empty.
|
// empty.
|
||||||
@@ -192,8 +241,8 @@ superblock * hoardHeap::removeMaxSuperblock (int sizeclass)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void hoardHeap::removeSuperblock (superblock * sb,
|
void
|
||||||
int sizeclass)
|
hoardHeap::removeSuperblock(superblock *sb, int sizeclass)
|
||||||
{
|
{
|
||||||
assert(_magic == HEAP_MAGIC);
|
assert(_magic == HEAP_MAGIC);
|
||||||
|
|
||||||
@@ -212,14 +261,14 @@ void hoardHeap::removeSuperblock (superblock * sb,
|
|||||||
}
|
}
|
||||||
|
|
||||||
sb->remove();
|
sb->remove();
|
||||||
decStats (sizeclass, sb->getNumBlocks() - sb->getNumAvailable(), sb->getNumBlocks());
|
decStats(sizeclass, sb->getNumBlocks() - sb->getNumAvailable(),
|
||||||
|
sb->getNumBlocks());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void hoardHeap::moveSuperblock (superblock * sb,
|
void
|
||||||
int sizeclass,
|
hoardHeap::moveSuperblock(superblock *sb,
|
||||||
int fromBin,
|
int sizeclass, int fromBin, int toBin)
|
||||||
int toBin)
|
|
||||||
{
|
{
|
||||||
assert(_magic == HEAP_MAGIC);
|
assert(_magic == HEAP_MAGIC);
|
||||||
assert(sb->isValid());
|
assert(sb->isValid());
|
||||||
@@ -253,10 +302,9 @@ void hoardHeap::moveSuperblock (superblock * sb,
|
|||||||
|
|
||||||
// The heap lock must be held when this procedure is called.
|
// The heap lock must be held when this procedure is called.
|
||||||
|
|
||||||
int hoardHeap::freeBlock (block *& b,
|
int
|
||||||
superblock *& sb,
|
hoardHeap::freeBlock(block * &b, superblock * &sb,
|
||||||
int sizeclass,
|
int sizeclass, processHeap *pHeap)
|
||||||
processHeap * pHeap)
|
|
||||||
{
|
{
|
||||||
assert(sb->isValid());
|
assert(sb->isValid());
|
||||||
assert(b->isValid());
|
assert(b->isValid());
|
||||||
@@ -275,11 +323,13 @@ int hoardHeap::freeBlock (block *& b,
|
|||||||
#if HEAP_LOG
|
#if HEAP_LOG
|
||||||
// Record the memory deallocation.
|
// Record the memory deallocation.
|
||||||
MemoryRequest m;
|
MemoryRequest m;
|
||||||
m.deallocate ((int) sb->getNumBlocks() * (int) sizeFromClass(sb->getBlockSizeClass()));
|
m.deallocate((int)sb->getNumBlocks()
|
||||||
|
* (int)sizeFromClass(sb->getBlockSizeClass()));
|
||||||
pHeap->getLog(getIndex()).append(m);
|
pHeap->getLog(getIndex()).append(m);
|
||||||
#endif
|
#endif
|
||||||
#if HEAP_FRAG_STATS
|
#if HEAP_FRAG_STATS
|
||||||
pHeap->setDeallocated (0, sb->getNumBlocks() * sizeFromClass(sb->getBlockSizeClass()));
|
pHeap->setDeallocated(0,
|
||||||
|
sb->getNumBlocks() * sizeFromClass(sb->getBlockSizeClass()));
|
||||||
#endif
|
#endif
|
||||||
hoardUnsbrk(sb, align(sizeof(superblock) + blksize));
|
hoardUnsbrk(sb, align(sizeof(superblock) + blksize));
|
||||||
return 1;
|
return 1;
|
||||||
@@ -301,8 +351,7 @@ int hoardHeap::freeBlock (block *& b,
|
|||||||
|
|
||||||
// If the superblock is now empty, recycle it.
|
// If the superblock is now empty, recycle it.
|
||||||
|
|
||||||
if ((newFullness == 0) &&
|
if ((newFullness == 0) && (sb->getNumBlocks() == sb->getNumAvailable())) {
|
||||||
(sb->getNumBlocks() == sb->getNumAvailable())) {
|
|
||||||
removeSuperblock(sb, sizeclass);
|
removeSuperblock(sb, sizeclass);
|
||||||
#if 0
|
#if 0
|
||||||
// Free it immediately.
|
// Free it immediately.
|
||||||
@@ -311,12 +360,15 @@ int hoardHeap::freeBlock (block *& b,
|
|||||||
#if HEAP_LOG
|
#if HEAP_LOG
|
||||||
// Record the memory deallocation.
|
// Record the memory deallocation.
|
||||||
MemoryRequest m;
|
MemoryRequest m;
|
||||||
m.deallocate ((int) sb->getNumBlocks() * (int) sizeFromClass(sb->getBlockSizeClass()));
|
m.deallocate((int)sb->getNumBlocks()
|
||||||
|
* (int)sizeFromClass(sb->getBlockSizeClass()));
|
||||||
pHeap->getLog(getIndex()).append(m);
|
pHeap->getLog(getIndex()).append(m);
|
||||||
#endif
|
#endif
|
||||||
#if HEAP_FRAG_STATS
|
#if HEAP_FRAG_STATS
|
||||||
pHeap->setDeallocated (0, sb->getNumBlocks() * sizeFromClass(sb->getBlockSizeClass()));
|
pHeap->setDeallocated(0,
|
||||||
|
sb->getNumBlocks() * sizeFromClass(sb->getBlockSizeClass()));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
hoardUnsbrk(sb, align(sizeof(superblock) + blksize));
|
hoardUnsbrk(sb, align(sizeof(superblock) + blksize));
|
||||||
return 1;
|
return 1;
|
||||||
#else
|
#else
|
||||||
@@ -324,15 +376,13 @@ int hoardHeap::freeBlock (block *& b,
|
|||||||
// Update the stats. This restores the stats to their state
|
// Update the stats. This restores the stats to their state
|
||||||
// before the call to removeSuperblock, above.
|
// before the call to removeSuperblock, above.
|
||||||
incStats(sizeclass,
|
incStats(sizeclass,
|
||||||
sb->getNumBlocks() - sb->getNumAvailable(),
|
sb->getNumBlocks() - sb->getNumAvailable(), sb->getNumBlocks());
|
||||||
sb->getNumBlocks());
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this is the process heap, then we're done.
|
// If this is the process heap, then we're done.
|
||||||
if (this == (hoardHeap *) pHeap) {
|
if (this == (hoardHeap *)pHeap)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Release a superblock, if necessary.
|
// Release a superblock, if necessary.
|
||||||
@@ -350,7 +400,8 @@ int hoardHeap::freeBlock (block *& b,
|
|||||||
int inUse, allocated;
|
int inUse, allocated;
|
||||||
getStats(sizeclass, inUse, allocated);
|
getStats(sizeclass, inUse, allocated);
|
||||||
if ((inUse < allocated - getReleaseThreshold(sizeclass))
|
if ((inUse < allocated - getReleaseThreshold(sizeclass))
|
||||||
&& (EMPTY_FRACTION * inUse < EMPTY_FRACTION * allocated - allocated)) {
|
&& (EMPTY_FRACTION * inUse <
|
||||||
|
EMPTY_FRACTION * allocated - allocated)) {
|
||||||
|
|
||||||
// We've crossed the magical threshold. Find the superblock with
|
// We've crossed the magical threshold. Find the superblock with
|
||||||
// the most free blocks and give it to the process heap.
|
// the most free blocks and give it to the process heap.
|
||||||
@@ -363,7 +414,6 @@ int hoardHeap::freeBlock (block *& b,
|
|||||||
|
|
||||||
// Give the superblock back to the process heap.
|
// Give the superblock back to the process heap.
|
||||||
pHeap->release(maxSb);
|
pHeap->release(maxSb);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -378,7 +428,8 @@ int hoardHeap::_numProcessorsMask;
|
|||||||
hoardHeap::_initNumProcs::_initNumProcs(void)
|
hoardHeap::_initNumProcs::_initNumProcs(void)
|
||||||
{
|
{
|
||||||
hoardHeap::_numProcessors = hoardGetNumProcessors();
|
hoardHeap::_numProcessors = hoardGetNumProcessors();
|
||||||
hoardHeap::_numProcessorsMask = (1 << (lg(hoardGetNumProcessors()) + 1)) - 1;
|
hoardHeap::_numProcessorsMask =
|
||||||
|
(1 << (lg(hoardGetNumProcessors()) + 1)) - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static hoardHeap::_initNumProcs initProcs;
|
static hoardHeap::_initNumProcs initProcs;
|
||||||
|
|||||||
@@ -30,13 +30,13 @@
|
|||||||
#include "superblock.h"
|
#include "superblock.h"
|
||||||
#include "heapstats.h"
|
#include "heapstats.h"
|
||||||
|
|
||||||
class processHeap; // forward declaration
|
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
class processHeap;
|
||||||
|
|
||||||
class hoardHeap {
|
class hoardHeap {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
hoardHeap(void);
|
hoardHeap(void);
|
||||||
|
|
||||||
// A superblock that holds more than one object must hold at least
|
// A superblock that holds more than one object must hold at least
|
||||||
@@ -105,17 +105,14 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Insert a superblock into our list.
|
// Insert a superblock into our list.
|
||||||
void insertSuperblock (int sizeclass,
|
void insertSuperblock(int sizeclass, superblock *sb, processHeap *pHeap);
|
||||||
superblock * sb,
|
|
||||||
processHeap * pHeap);
|
|
||||||
|
|
||||||
// Remove the superblock with the most free space.
|
// Remove the superblock with the most free space.
|
||||||
superblock *removeMaxSuperblock(int sizeclass);
|
superblock *removeMaxSuperblock(int sizeclass);
|
||||||
|
|
||||||
// Find an available superblock (i.e., with some space in it).
|
// Find an available superblock (i.e., with some space in it).
|
||||||
inline superblock *findAvailableSuperblock(int sizeclass,
|
inline superblock *findAvailableSuperblock(int sizeclass,
|
||||||
block *& b,
|
block * &b, processHeap * pHeap);
|
||||||
processHeap * pHeap);
|
|
||||||
|
|
||||||
// Lock this heap.
|
// Lock this heap.
|
||||||
inline void lock(void);
|
inline void lock(void);
|
||||||
@@ -132,9 +129,7 @@ public:
|
|||||||
// Free a block into a superblock.
|
// Free a block into a superblock.
|
||||||
// This is used by processHeap::free().
|
// This is used by processHeap::free().
|
||||||
// Returns 1 iff the superblock was munmapped.
|
// Returns 1 iff the superblock was munmapped.
|
||||||
int freeBlock (block *& b,
|
int freeBlock(block * &b, superblock * &sb, int sizeclass,
|
||||||
superblock *& sb,
|
|
||||||
int sizeclass,
|
|
||||||
processHeap * pHeap);
|
processHeap * pHeap);
|
||||||
|
|
||||||
//// Utility functions ////
|
//// Utility functions ////
|
||||||
@@ -155,7 +150,6 @@ public:
|
|||||||
inline static size_t align(const size_t sz);
|
inline static size_t align(const size_t sz);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// Disable copying and assignment.
|
// Disable copying and assignment.
|
||||||
|
|
||||||
hoardHeap(const hoardHeap &);
|
hoardHeap(const hoardHeap &);
|
||||||
@@ -172,9 +166,7 @@ private:
|
|||||||
|
|
||||||
// Move a particular superblock from one bin to another.
|
// Move a particular superblock from one bin to another.
|
||||||
void moveSuperblock(superblock *,
|
void moveSuperblock(superblock *,
|
||||||
int sizeclass,
|
int sizeclass, int fromBin, int toBin);
|
||||||
int fromBin,
|
|
||||||
int toBin);
|
|
||||||
|
|
||||||
// Update memory in-use and allocated statistics.
|
// Update memory in-use and allocated statistics.
|
||||||
// (*UStats = just update U.)
|
// (*UStats = just update U.)
|
||||||
@@ -226,6 +218,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
friend class _initNumProcs;
|
friend class _initNumProcs;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// number of CPUs, cached
|
// number of CPUs, cached
|
||||||
static int _numProcessors;
|
static int _numProcessors;
|
||||||
@@ -234,7 +227,9 @@ protected:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void hoardHeap::incStats (int sizeclass, int updateU, int updateA) {
|
void
|
||||||
|
hoardHeap::incStats(int sizeclass, int updateU, int updateA)
|
||||||
|
{
|
||||||
assert(_magic == HEAP_MAGIC);
|
assert(_magic == HEAP_MAGIC);
|
||||||
assert(updateU >= 0);
|
assert(updateU >= 0);
|
||||||
assert(updateA >= 0);
|
assert(updateA >= 0);
|
||||||
@@ -244,8 +239,9 @@ void hoardHeap::incStats (int sizeclass, int updateU, int updateA) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
void hoardHeap::incUStats (int sizeclass) {
|
hoardHeap::incUStats(int sizeclass)
|
||||||
|
{
|
||||||
assert(_magic == HEAP_MAGIC);
|
assert(_magic == HEAP_MAGIC);
|
||||||
assert(sizeclass >= 0);
|
assert(sizeclass >= 0);
|
||||||
assert(sizeclass < SIZE_CLASSES);
|
assert(sizeclass < SIZE_CLASSES);
|
||||||
@@ -253,7 +249,9 @@ void hoardHeap::incUStats (int sizeclass) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void hoardHeap::decStats (int sizeclass, int updateU, int updateA) {
|
void
|
||||||
|
hoardHeap::decStats(int sizeclass, int updateU, int updateA)
|
||||||
|
{
|
||||||
assert(_magic == HEAP_MAGIC);
|
assert(_magic == HEAP_MAGIC);
|
||||||
assert(updateU >= 0);
|
assert(updateU >= 0);
|
||||||
assert(updateA >= 0);
|
assert(updateA >= 0);
|
||||||
@@ -263,7 +261,8 @@ void hoardHeap::decStats (int sizeclass, int updateU, int updateA) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void hoardHeap::decUStats (int sizeclass)
|
void
|
||||||
|
hoardHeap::decUStats(int sizeclass)
|
||||||
{
|
{
|
||||||
assert(_magic == HEAP_MAGIC);
|
assert(_magic == HEAP_MAGIC);
|
||||||
assert(sizeclass >= 0);
|
assert(sizeclass >= 0);
|
||||||
@@ -272,7 +271,9 @@ void hoardHeap::decUStats (int sizeclass)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void hoardHeap::getStats (int sizeclass, int& U, int& A) {
|
void
|
||||||
|
hoardHeap::getStats(int sizeclass, int &U, int &A)
|
||||||
|
{
|
||||||
assert(_magic == HEAP_MAGIC);
|
assert(_magic == HEAP_MAGIC);
|
||||||
assert(sizeclass >= 0);
|
assert(sizeclass >= 0);
|
||||||
assert(sizeclass < SIZE_CLASSES);
|
assert(sizeclass < SIZE_CLASSES);
|
||||||
@@ -281,22 +282,26 @@ void hoardHeap::getStats (int sizeclass, int& U, int& A) {
|
|||||||
|
|
||||||
|
|
||||||
#if HEAP_STATS
|
#if HEAP_STATS
|
||||||
int hoardHeap::maxInUse (int sizeclass) {
|
int
|
||||||
|
hoardHeap::maxInUse(int sizeclass)
|
||||||
|
{
|
||||||
assert(_magic == HEAP_MAGIC);
|
assert(_magic == HEAP_MAGIC);
|
||||||
return _stats[sizeclass].getUmax();
|
return _stats[sizeclass].getUmax();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int hoardHeap::maxAllocated (int sizeclass) {
|
int
|
||||||
|
hoardHeap::maxAllocated(int sizeclass)
|
||||||
|
{
|
||||||
assert(_magic == HEAP_MAGIC);
|
assert(_magic == HEAP_MAGIC);
|
||||||
return _stats[sizeclass].getAmax();
|
return _stats[sizeclass].getAmax();
|
||||||
}
|
}
|
||||||
#endif
|
#endif // HEAP_STATS
|
||||||
|
|
||||||
|
|
||||||
superblock * hoardHeap::findAvailableSuperblock (int sizeclass,
|
superblock *
|
||||||
block *& b,
|
hoardHeap::findAvailableSuperblock(int sizeclass,
|
||||||
processHeap * pHeap)
|
block * &b, processHeap * pHeap)
|
||||||
{
|
{
|
||||||
assert(this);
|
assert(this);
|
||||||
assert(_magic == HEAP_MAGIC);
|
assert(_magic == HEAP_MAGIC);
|
||||||
@@ -373,7 +378,6 @@ superblock * hoardHeap::findAvailableSuperblock (int sizeclass,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Either we didn't find a superblock or we did and got a block.
|
// Either we didn't find a superblock or we did and got a block.
|
||||||
assert((sb == NULL) || (b != NULL));
|
assert((sb == NULL) || (b != NULL));
|
||||||
// Either we didn't get a block or we did and we also got a superblock.
|
// Either we didn't get a block or we did and we also got a superblock.
|
||||||
@@ -383,12 +387,13 @@ superblock * hoardHeap::findAvailableSuperblock (int sizeclass,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int hoardHeap::sizeClass (const size_t sz) {
|
int
|
||||||
|
hoardHeap::sizeClass(const size_t sz)
|
||||||
|
{
|
||||||
// Find the size class for a given object size
|
// Find the size class for a given object size
|
||||||
// (the smallest i such that _sizeTable[i] >= sz).
|
// (the smallest i such that _sizeTable[i] >= sz).
|
||||||
int sizeclass = 0;
|
int sizeclass = 0;
|
||||||
while (_sizeTable[sizeclass] < sz)
|
while (_sizeTable[sizeclass] < sz) {
|
||||||
{
|
|
||||||
sizeclass++;
|
sizeclass++;
|
||||||
assert(sizeclass < SIZE_CLASSES);
|
assert(sizeclass < SIZE_CLASSES);
|
||||||
}
|
}
|
||||||
@@ -396,21 +401,27 @@ int hoardHeap::sizeClass (const size_t sz) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
size_t hoardHeap::sizeFromClass (const int sizeclass) {
|
size_t
|
||||||
|
hoardHeap::sizeFromClass(const int sizeclass)
|
||||||
|
{
|
||||||
assert(sizeclass >= 0);
|
assert(sizeclass >= 0);
|
||||||
assert(sizeclass < SIZE_CLASSES);
|
assert(sizeclass < SIZE_CLASSES);
|
||||||
return _sizeTable[sizeclass];
|
return _sizeTable[sizeclass];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int hoardHeap::getReleaseThreshold (const int sizeclass) {
|
int
|
||||||
|
hoardHeap::getReleaseThreshold(const int sizeclass)
|
||||||
|
{
|
||||||
assert(sizeclass >= 0);
|
assert(sizeclass >= 0);
|
||||||
assert(sizeclass < SIZE_CLASSES);
|
assert(sizeclass < SIZE_CLASSES);
|
||||||
return _threshold[sizeclass];
|
return _threshold[sizeclass];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int hoardHeap::numBlocks (const int sizeclass) {
|
int
|
||||||
|
hoardHeap::numBlocks(const int sizeclass)
|
||||||
|
{
|
||||||
assert(sizeclass >= 0);
|
assert(sizeclass >= 0);
|
||||||
assert(sizeclass < SIZE_CLASSES);
|
assert(sizeclass < SIZE_CLASSES);
|
||||||
const size_t s = sizeFromClass(sizeclass);
|
const size_t s = sizeFromClass(sizeclass);
|
||||||
@@ -422,20 +433,24 @@ int hoardHeap::numBlocks (const int sizeclass) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void hoardHeap::lock (void)
|
void
|
||||||
|
hoardHeap::lock(void)
|
||||||
{
|
{
|
||||||
assert(_magic == HEAP_MAGIC);
|
assert(_magic == HEAP_MAGIC);
|
||||||
hoardLock(_lock);
|
hoardLock(_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void hoardHeap::unlock (void) {
|
void
|
||||||
|
hoardHeap::unlock(void)
|
||||||
|
{
|
||||||
assert(_magic == HEAP_MAGIC);
|
assert(_magic == HEAP_MAGIC);
|
||||||
hoardUnlock(_lock);
|
hoardUnlock(_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
size_t hoardHeap::align (const size_t sz)
|
size_t
|
||||||
|
hoardHeap::align(const size_t sz)
|
||||||
{
|
{
|
||||||
// Align sz up to the nearest multiple of ALIGNMENT.
|
// Align sz up to the nearest multiple of ALIGNMENT.
|
||||||
// This is much faster than using multiplication
|
// This is much faster than using multiplication
|
||||||
@@ -444,21 +459,22 @@ size_t hoardHeap::align (const size_t sz)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void hoardHeap::setIndex (int i)
|
void
|
||||||
|
hoardHeap::setIndex(int i)
|
||||||
{
|
{
|
||||||
_index = i;
|
_index = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int hoardHeap::getIndex (void)
|
int
|
||||||
|
hoardHeap::getIndex(void)
|
||||||
{
|
{
|
||||||
return _index;
|
return _index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
hoardHeap::recycle(superblock *sb)
|
||||||
void hoardHeap::recycle (superblock * sb)
|
|
||||||
{
|
{
|
||||||
assert(sb != NULL);
|
assert(sb != NULL);
|
||||||
assert(sb->getOwner() == this);
|
assert(sb->getOwner() == this);
|
||||||
@@ -473,17 +489,16 @@ void hoardHeap::recycle (superblock * sb)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
superblock * hoardHeap::reuse (int sizeclass)
|
superblock *
|
||||||
|
hoardHeap::reuse(int sizeclass)
|
||||||
{
|
{
|
||||||
if (_reusableSuperblocks == NULL) {
|
if (_reusableSuperblocks == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure that we aren't using a sizeclass
|
// Make sure that we aren't using a sizeclass
|
||||||
// that is too big for a 'normal' superblock.
|
// that is too big for a 'normal' superblock.
|
||||||
if (hoardHeap::numBlocks(sizeclass) <= 1) {
|
if (hoardHeap::numBlocks(sizeclass) <= 1)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
|
|
||||||
// Pop off a superblock from the reusable-superblock list.
|
// Pop off a superblock from the reusable-superblock list.
|
||||||
assert(_reusableSuperblocksCount > 0);
|
assert(_reusableSuperblocksCount > 0);
|
||||||
@@ -499,7 +514,8 @@ superblock * hoardHeap::reuse (int sizeclass)
|
|||||||
sb->getNumBlocks() - sb->getNumAvailable(),
|
sb->getNumBlocks() - sb->getNumAvailable(),
|
||||||
sb->getNumBlocks());
|
sb->getNumBlocks());
|
||||||
|
|
||||||
sb = new ((char *) sb) superblock (numBlocks(sizeclass), sizeclass, this);
|
sb = new((char *)sb) superblock(numBlocks(sizeclass),
|
||||||
|
sizeclass, this);
|
||||||
|
|
||||||
incStats(sizeclass,
|
incStats(sizeclass,
|
||||||
sb->getNumBlocks() - sb->getNumAvailable(),
|
sb->getNumBlocks() - sb->getNumAvailable(),
|
||||||
@@ -511,4 +527,6 @@ superblock * hoardHeap::reuse (int sizeclass)
|
|||||||
return sb;
|
return sb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
#endif // _HEAP_H_
|
#endif // _HEAP_H_
|
||||||
|
|||||||
@@ -27,16 +27,13 @@
|
|||||||
|
|
||||||
class heapStats {
|
class heapStats {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
heapStats(void)
|
heapStats(void)
|
||||||
:
|
: U(0), A(0)
|
||||||
U (0),
|
|
||||||
A (0)
|
|
||||||
#if HEAP_STATS
|
#if HEAP_STATS
|
||||||
,Umax (0),
|
, Umax(0), Amax(0)
|
||||||
Amax (0)
|
|
||||||
#endif
|
#endif
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
inline const heapStats & operator=(const heapStats & p);
|
inline const heapStats & operator=(const heapStats & p);
|
||||||
|
|
||||||
@@ -49,17 +46,12 @@ public:
|
|||||||
|
|
||||||
inline void getStats(int &Uout, int &Aout);
|
inline void getStats(int &Uout, int &Aout);
|
||||||
|
|
||||||
|
|
||||||
#if HEAP_STATS
|
#if HEAP_STATS
|
||||||
|
|
||||||
inline int getUmax(void);
|
inline int getUmax(void);
|
||||||
inline int getAmax(void);
|
inline int getAmax(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// U and A *must* be the first items in this class --
|
// U and A *must* be the first items in this class --
|
||||||
// we will depend on this to atomically update them.
|
// we will depend on this to atomically update them.
|
||||||
|
|
||||||
@@ -73,7 +65,8 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
inline void heapStats::incStats (int updateU, int updateA)
|
inline void
|
||||||
|
heapStats::incStats(int updateU, int updateA)
|
||||||
{
|
{
|
||||||
assert(updateU >= 0);
|
assert(updateU >= 0);
|
||||||
assert(updateA >= 0);
|
assert(updateA >= 0);
|
||||||
@@ -82,31 +75,37 @@ inline void heapStats::incStats (int updateU, int updateA)
|
|||||||
assert(A >= 0);
|
assert(A >= 0);
|
||||||
U += updateU;
|
U += updateU;
|
||||||
A += updateA;
|
A += updateA;
|
||||||
|
|
||||||
#if HEAP_STATS
|
#if HEAP_STATS
|
||||||
Amax = MAX(Amax, A);
|
Amax = MAX(Amax, A);
|
||||||
Umax = MAX(Umax, U);
|
Umax = MAX(Umax, U);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
assert(U <= A);
|
assert(U <= A);
|
||||||
assert(U >= 0);
|
assert(U >= 0);
|
||||||
assert(A >= 0);
|
assert(A >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline void heapStats::incUStats (void)
|
inline void
|
||||||
|
heapStats::incUStats(void)
|
||||||
{
|
{
|
||||||
assert(U < A);
|
assert(U < A);
|
||||||
assert(U >= 0);
|
assert(U >= 0);
|
||||||
assert(A >= 0);
|
assert(A >= 0);
|
||||||
U++;
|
U++;
|
||||||
|
|
||||||
#if HEAP_STATS
|
#if HEAP_STATS
|
||||||
Umax = MAX(Umax, U);
|
Umax = MAX(Umax, U);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
assert(U >= 0);
|
assert(U >= 0);
|
||||||
assert(A >= 0);
|
assert(A >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline void heapStats::decStats (int updateU, int updateA)
|
inline void
|
||||||
|
heapStats::decStats(int updateU, int updateA)
|
||||||
{
|
{
|
||||||
assert(updateU >= 0);
|
assert(updateU >= 0);
|
||||||
assert(updateA >= 0);
|
assert(updateA >= 0);
|
||||||
@@ -121,7 +120,8 @@ inline void heapStats::decStats (int updateU, int updateA)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline void heapStats::decUStats (int& Uout, int& Aout)
|
inline void
|
||||||
|
heapStats::decUStats(int &Uout, int &Aout)
|
||||||
{
|
{
|
||||||
assert(U <= A);
|
assert(U <= A);
|
||||||
assert(U > 0);
|
assert(U > 0);
|
||||||
@@ -134,7 +134,8 @@ inline void heapStats::decUStats (int& Uout, int& Aout)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline void heapStats::decUStats (void)
|
inline void
|
||||||
|
heapStats::decUStats(void)
|
||||||
{
|
{
|
||||||
assert(U <= A);
|
assert(U <= A);
|
||||||
assert(U > 0);
|
assert(U > 0);
|
||||||
@@ -143,7 +144,8 @@ inline void heapStats::decUStats (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline void heapStats::getStats (int& Uout, int& Aout)
|
inline void
|
||||||
|
heapStats::getStats(int &Uout, int &Aout)
|
||||||
{
|
{
|
||||||
assert(U >= 0);
|
assert(U >= 0);
|
||||||
assert(A >= 0);
|
assert(A >= 0);
|
||||||
@@ -156,18 +158,18 @@ inline void heapStats::getStats (int& Uout, int& Aout)
|
|||||||
|
|
||||||
|
|
||||||
#if HEAP_STATS
|
#if HEAP_STATS
|
||||||
inline int heapStats::getUmax (void)
|
inline int
|
||||||
|
heapStats::getUmax(void)
|
||||||
{
|
{
|
||||||
return Umax;
|
return Umax;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline int heapStats::getAmax (void)
|
inline int
|
||||||
|
heapStats::getAmax(void)
|
||||||
{
|
{
|
||||||
return Amax;
|
return Amax;
|
||||||
}
|
}
|
||||||
#endif // HEAP_STATS
|
#endif // HEAP_STATS
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif // _HEAPSTATS_H_
|
#endif // _HEAPSTATS_H_
|
||||||
|
|||||||
@@ -32,16 +32,15 @@
|
|||||||
|
|
||||||
#include "processheap.h"
|
#include "processheap.h"
|
||||||
|
|
||||||
|
using namespace BPrivate;
|
||||||
|
|
||||||
|
|
||||||
processHeap::processHeap(void)
|
processHeap::processHeap(void)
|
||||||
: _buffer (NULL),
|
: _buffer(NULL), _bufferCount(0)
|
||||||
_bufferCount (0)
|
|
||||||
#if HEAP_FRAG_STATS
|
#if HEAP_FRAG_STATS
|
||||||
, _currentAllocated(0),
|
, _currentAllocated(0),
|
||||||
_currentRequested(0),
|
_currentRequested(0),
|
||||||
_maxAllocated (0),
|
_maxAllocated(0), _inUseAtMaxAllocated(0), _maxRequested(0)
|
||||||
_inUseAtMaxAllocated (0),
|
|
||||||
_maxRequested (0)
|
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@@ -69,7 +68,9 @@ processHeap::processHeap (void)
|
|||||||
|
|
||||||
|
|
||||||
// Print out statistics information.
|
// Print out statistics information.
|
||||||
void processHeap::stats (void) {
|
void
|
||||||
|
processHeap::stats(void)
|
||||||
|
{
|
||||||
#if HEAP_STATS
|
#if HEAP_STATS
|
||||||
int umax = 0;
|
int umax = 0;
|
||||||
int amax = 0;
|
int amax = 0;
|
||||||
@@ -80,16 +81,20 @@ void processHeap::stats (void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
printf("Amax <= %d, Umax <= %d\n", amax, umax);
|
printf("Amax <= %d, Umax <= %d\n", amax, umax);
|
||||||
|
|
||||||
#if HEAP_FRAG_STATS
|
#if HEAP_FRAG_STATS
|
||||||
amax = getMaxAllocated();
|
amax = getMaxAllocated();
|
||||||
umax = getMaxRequested();
|
umax = getMaxRequested();
|
||||||
printf ("Maximum allocated = %d\nMaximum in use = %d\nIn use at max allocated = %d\n", amax, umax, getInUseAtMaxAllocated());
|
printf
|
||||||
|
("Maximum allocated = %d\nMaximum in use = %d\nIn use at max allocated = %d\n",
|
||||||
|
amax, umax, getInUseAtMaxAllocated());
|
||||||
printf("Still in use = %d\n", _currentRequested);
|
printf("Still in use = %d\n", _currentRequested);
|
||||||
printf ("Fragmentation (3) = %f\n", (float) amax / (float) getInUseAtMaxAllocated());
|
printf("Fragmentation (3) = %f\n",
|
||||||
|
(float)amax / (float)getInUseAtMaxAllocated());
|
||||||
printf("Fragmentation (4) = %f\n", (float)amax / (float)umax);
|
printf("Fragmentation (4) = %f\n", (float)amax / (float)umax);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // HEAP_STATS
|
#endif // HEAP_STATS
|
||||||
|
|
||||||
#if HEAP_LOG
|
#if HEAP_LOG
|
||||||
printf("closing logs.\n");
|
printf("closing logs.\n");
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
@@ -100,10 +105,9 @@ void processHeap::stats (void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if HEAP_FRAG_STATS
|
#if HEAP_FRAG_STATS
|
||||||
void processHeap::setAllocated (int requestedSize,
|
void
|
||||||
int actualSize)
|
processHeap::setAllocated(int requestedSize, int actualSize)
|
||||||
{
|
{
|
||||||
hoardLock(_statsLock);
|
hoardLock(_statsLock);
|
||||||
_currentRequested += requestedSize;
|
_currentRequested += requestedSize;
|
||||||
@@ -119,15 +123,15 @@ void processHeap::setAllocated (int requestedSize,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void processHeap::setDeallocated (int requestedSize,
|
void
|
||||||
int actualSize)
|
processHeap::setDeallocated(int requestedSize, int actualSize)
|
||||||
{
|
{
|
||||||
hoardLock(_statsLock);
|
hoardLock(_statsLock);
|
||||||
_currentRequested -= requestedSize;
|
_currentRequested -= requestedSize;
|
||||||
_currentAllocated -= actualSize;
|
_currentAllocated -= actualSize;
|
||||||
hoardUnlock(_statsLock);
|
hoardUnlock(_statsLock);
|
||||||
}
|
}
|
||||||
#endif
|
#endif // HEAP_FRAG_STATS
|
||||||
|
|
||||||
|
|
||||||
// free (ptr, pheap):
|
// free (ptr, pheap):
|
||||||
@@ -136,14 +140,13 @@ void processHeap::setDeallocated (int requestedSize,
|
|||||||
// updates the thread heap's statistics;
|
// updates the thread heap's statistics;
|
||||||
// may release the superblock to the process heap.
|
// may release the superblock to the process heap.
|
||||||
|
|
||||||
void processHeap::free (void * ptr)
|
void
|
||||||
|
processHeap::free(void *ptr)
|
||||||
{
|
{
|
||||||
|
|
||||||
// Return if ptr is 0.
|
// Return if ptr is 0.
|
||||||
// This is the behavior prescribed by the standard.
|
// This is the behavior prescribed by the standard.
|
||||||
if (ptr == 0) {
|
if (ptr == 0)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
// Find the block and superblock corresponding to this ptr.
|
// Find the block and superblock corresponding to this ptr.
|
||||||
|
|
||||||
@@ -203,7 +206,6 @@ void processHeap::free (void * ptr)
|
|||||||
int sbUnmapped = owner->freeBlock(b, sb, sizeclass, this);
|
int sbUnmapped = owner->freeBlock(b, sb, sizeclass, this);
|
||||||
|
|
||||||
owner->unlock();
|
owner->unlock();
|
||||||
if (!sbUnmapped) {
|
if (!sbUnmapped)
|
||||||
sb->upUnlock();
|
sb->upUnlock();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -42,22 +42,22 @@
|
|||||||
# include "log.h"
|
# include "log.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
class processHeap : public hoardHeap {
|
class processHeap : public hoardHeap {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// Always grab at least this many superblocks' worth of memory which
|
// Always grab at least this many superblocks' worth of memory which
|
||||||
// we parcel out.
|
// we parcel out.
|
||||||
enum { REFILL_NUMBER_OF_SUPERBLOCKS = 16 };
|
enum { REFILL_NUMBER_OF_SUPERBLOCKS = 16 };
|
||||||
|
|
||||||
processHeap(void);
|
processHeap(void);
|
||||||
|
~processHeap(void)
|
||||||
~processHeap (void) {
|
{
|
||||||
#if HEAP_STATS
|
#if HEAP_STATS
|
||||||
stats();
|
stats();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Memory deallocation routines.
|
// Memory deallocation routines.
|
||||||
void free(void *ptr);
|
void free(void *ptr);
|
||||||
|
|
||||||
@@ -71,8 +71,7 @@ public:
|
|||||||
inline HEAPTYPE & getHeap(int i);
|
inline HEAPTYPE & getHeap(int i);
|
||||||
|
|
||||||
// Extract a superblock.
|
// Extract a superblock.
|
||||||
inline superblock * acquire (const int c,
|
inline superblock *acquire(const int c, hoardHeap * dest);
|
||||||
hoardHeap * dest);
|
|
||||||
|
|
||||||
// Get space for a superblock.
|
// Get space for a superblock.
|
||||||
inline char *getSuperblockBuffer(void);
|
inline char *getSuperblockBuffer(void);
|
||||||
@@ -87,40 +86,45 @@ public:
|
|||||||
|
|
||||||
#if HEAP_FRAG_STATS
|
#if HEAP_FRAG_STATS
|
||||||
// Declare that we have allocated an object.
|
// Declare that we have allocated an object.
|
||||||
void setAllocated (int requestedSize,
|
void setAllocated(int requestedSize, int actualSize);
|
||||||
int actualSize);
|
|
||||||
|
|
||||||
// Declare that we have deallocated an object.
|
// Declare that we have deallocated an object.
|
||||||
void setDeallocated (int requestedSize,
|
void setDeallocated(int requestedSize, int actualSize);
|
||||||
int actualSize);
|
|
||||||
|
|
||||||
// Return the number of wasted bytes at the high-water mark
|
// Return the number of wasted bytes at the high-water mark
|
||||||
// (maxAllocated - maxRequested)
|
// (maxAllocated - maxRequested)
|
||||||
inline int getFragmentation(void);
|
inline int getFragmentation(void);
|
||||||
|
|
||||||
int getMaxAllocated (void) {
|
int
|
||||||
|
getMaxAllocated(void)
|
||||||
|
{
|
||||||
return _maxAllocated;
|
return _maxAllocated;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getInUseAtMaxAllocated (void) {
|
int
|
||||||
|
getInUseAtMaxAllocated(void)
|
||||||
|
{
|
||||||
return _inUseAtMaxAllocated;
|
return _inUseAtMaxAllocated;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getMaxRequested (void) {
|
int
|
||||||
|
getMaxRequested(void)
|
||||||
|
{
|
||||||
return _maxRequested;
|
return _maxRequested;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// Hide the lock & unlock methods.
|
// Hide the lock & unlock methods.
|
||||||
|
void
|
||||||
void lock (void) {
|
lock(void)
|
||||||
|
{
|
||||||
hoardHeap::lock();
|
hoardHeap::lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void unlock (void) {
|
void
|
||||||
|
unlock(void)
|
||||||
|
{
|
||||||
hoardHeap::unlock();
|
hoardHeap::unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,7 +163,8 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
HEAPTYPE& processHeap::getHeap (int i)
|
HEAPTYPE &
|
||||||
|
processHeap::getHeap(int i)
|
||||||
{
|
{
|
||||||
assert(i >= 0);
|
assert(i >= 0);
|
||||||
assert(i < MAX_HEAPS);
|
assert(i < MAX_HEAPS);
|
||||||
@@ -168,7 +173,8 @@ HEAPTYPE& processHeap::getHeap (int i)
|
|||||||
|
|
||||||
|
|
||||||
#if HEAP_LOG
|
#if HEAP_LOG
|
||||||
Log<MemoryRequest>& processHeap::getLog (int i)
|
Log<MemoryRequest > &
|
||||||
|
processHeap::getLog(int i)
|
||||||
{
|
{
|
||||||
assert(i >= 0);
|
assert(i >= 0);
|
||||||
assert(i < MAX_HEAPS + 1);
|
assert(i < MAX_HEAPS + 1);
|
||||||
@@ -180,7 +186,8 @@ Log<MemoryRequest>& processHeap::getLog (int i)
|
|||||||
#ifdef NEED_LG
|
#ifdef NEED_LG
|
||||||
// Return ceil(log_2(num)).
|
// Return ceil(log_2(num)).
|
||||||
// num must be positive.
|
// num must be positive.
|
||||||
static int lg (int num)
|
static int
|
||||||
|
lg(int num)
|
||||||
{
|
{
|
||||||
assert(num > 0);
|
assert(num > 0);
|
||||||
int power = 0;
|
int power = 0;
|
||||||
@@ -195,7 +202,10 @@ static int lg (int num)
|
|||||||
#endif /* NEED_LG */
|
#endif /* NEED_LG */
|
||||||
|
|
||||||
// Hash out the thread id to a heap and return an index to that heap.
|
// Hash out the thread id to a heap and return an index to that heap.
|
||||||
int processHeap::getHeapIndex (void) {
|
|
||||||
|
int
|
||||||
|
processHeap::getHeapIndex(void)
|
||||||
|
{
|
||||||
// Here we use the number of processors as the maximum number of heaps.
|
// Here we use the number of processors as the maximum number of heaps.
|
||||||
// In fact, for efficiency, we just round up to the highest power of two,
|
// In fact, for efficiency, we just round up to the highest power of two,
|
||||||
// times two.
|
// times two.
|
||||||
@@ -205,16 +215,15 @@ int processHeap::getHeapIndex (void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
superblock * processHeap::acquire (const int sizeclass,
|
superblock *
|
||||||
hoardHeap * dest)
|
processHeap::acquire(const int sizeclass, hoardHeap * dest)
|
||||||
{
|
{
|
||||||
lock();
|
lock();
|
||||||
|
|
||||||
// Remove the superblock with the most free space.
|
// Remove the superblock with the most free space.
|
||||||
superblock *maxSb = removeMaxSuperblock(sizeclass);
|
superblock *maxSb = removeMaxSuperblock(sizeclass);
|
||||||
if (maxSb) {
|
if (maxSb)
|
||||||
maxSb->setOwner(dest);
|
maxSb->setOwner(dest);
|
||||||
}
|
|
||||||
|
|
||||||
unlock();
|
unlock();
|
||||||
|
|
||||||
@@ -222,24 +231,30 @@ superblock * processHeap::acquire (const int sizeclass,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline char * processHeap::getSuperblockBuffer (void)
|
inline char *
|
||||||
|
processHeap::getSuperblockBuffer(void)
|
||||||
{
|
{
|
||||||
char *buf;
|
char *buf;
|
||||||
hoardLock(_bufferLock);
|
hoardLock(_bufferLock);
|
||||||
if (_bufferCount == 0) {
|
if (_bufferCount == 0) {
|
||||||
_buffer = (char *) hoardSbrk (SUPERBLOCK_SIZE * REFILL_NUMBER_OF_SUPERBLOCKS);
|
_buffer = (char *)hoardSbrk(SUPERBLOCK_SIZE
|
||||||
|
* REFILL_NUMBER_OF_SUPERBLOCKS);
|
||||||
_bufferCount = REFILL_NUMBER_OF_SUPERBLOCKS;
|
_bufferCount = REFILL_NUMBER_OF_SUPERBLOCKS;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf = _buffer;
|
buf = _buffer;
|
||||||
_buffer += SUPERBLOCK_SIZE;
|
_buffer += SUPERBLOCK_SIZE;
|
||||||
_bufferCount--;
|
_bufferCount--;
|
||||||
hoardUnlock(_bufferLock);
|
hoardUnlock(_bufferLock);
|
||||||
|
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Put a superblock back into our list of superblocks.
|
// Put a superblock back into our list of superblocks.
|
||||||
void processHeap::release (superblock * sb)
|
|
||||||
|
void
|
||||||
|
processHeap::release(superblock *sb)
|
||||||
{
|
{
|
||||||
assert(EMPTY_FRACTION * sb->getNumAvailable() > sb->getNumBlocks());
|
assert(EMPTY_FRACTION * sb->getNumAvailable() > sb->getNumBlocks());
|
||||||
|
|
||||||
@@ -251,6 +266,6 @@ void processHeap::release (superblock * sb)
|
|||||||
unlock();
|
unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
#endif // _PROCESSHEAP_H_
|
#endif // _PROCESSHEAP_H_
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
The superblock class controls a number of blocks (which are
|
The superblock class controls a number of blocks (which are
|
||||||
allocatable units of memory).
|
allocatable units of memory).
|
||||||
------------------------------------------------------------------------
|
------------------------------------------------------------------------
|
||||||
@(#) $Id: superblock.cpp,v 1.2 2005/02/10 18:47:16 axeld Exp $
|
@(#) $Id$
|
||||||
------------------------------------------------------------------------
|
------------------------------------------------------------------------
|
||||||
Emery Berger | <http://www.cs.utexas.edu/users/emery>
|
Emery Berger | <http://www.cs.utexas.edu/users/emery>
|
||||||
Department of Computer Sciences | <http://www.cs.utexas.edu>
|
Department of Computer Sciences | <http://www.cs.utexas.edu>
|
||||||
@@ -39,6 +39,8 @@
|
|||||||
#include "processheap.h"
|
#include "processheap.h"
|
||||||
#include "superblock.h"
|
#include "superblock.h"
|
||||||
|
|
||||||
|
using namespace BPrivate;
|
||||||
|
|
||||||
|
|
||||||
superblock::superblock(int numBlocks, // The number of blocks in the sb.
|
superblock::superblock(int numBlocks, // The number of blocks in the sb.
|
||||||
int szclass, // The size class of the blocks.
|
int szclass, // The size class of the blocks.
|
||||||
@@ -50,24 +52,19 @@ superblock::superblock (int numBlocks, // The number of blocks in the sb.
|
|||||||
_sizeClass(szclass),
|
_sizeClass(szclass),
|
||||||
_numBlocks(numBlocks),
|
_numBlocks(numBlocks),
|
||||||
_numAvailable(0),
|
_numAvailable(0),
|
||||||
_fullness (0),
|
_fullness(0), _freeList(NULL), _owner(o), _next(NULL), _prev(NULL)
|
||||||
_freeList (NULL),
|
|
||||||
_owner (o),
|
|
||||||
_next (NULL),
|
|
||||||
_prev (NULL)
|
|
||||||
{
|
{
|
||||||
assert(_numBlocks >= 1);
|
assert(_numBlocks >= 1);
|
||||||
|
|
||||||
// Determine the size of each block.
|
// Determine the size of each block.
|
||||||
const int blksize =
|
const int blksize = hoardHeap::align(sizeof(block)
|
||||||
hoardHeap::align (sizeof(block) + hoardHeap::sizeFromClass(_sizeClass));
|
+ hoardHeap::sizeFromClass(_sizeClass));
|
||||||
|
|
||||||
// Make sure this size is in fact aligned.
|
// Make sure this size is in fact aligned.
|
||||||
assert((blksize & hoardHeap::ALIGNMENT_MASK) == 0);
|
assert((blksize & hoardHeap::ALIGNMENT_MASK) == 0);
|
||||||
|
|
||||||
// Set the first block to just past this superblock header.
|
// Set the first block to just past this superblock header.
|
||||||
block * b
|
block *b = (block *) hoardHeap::align((unsigned long)(this + 1));
|
||||||
= (block *) hoardHeap::align ((unsigned long) (this + 1));
|
|
||||||
|
|
||||||
// Initialize all the blocks,
|
// Initialize all the blocks,
|
||||||
// and insert the block pointers into the linked list.
|
// and insert the block pointers into the linked list.
|
||||||
@@ -80,15 +77,18 @@ superblock::superblock (int numBlocks, // The number of blocks in the sb.
|
|||||||
_freeList = b;
|
_freeList = b;
|
||||||
b = (block *)((char *)b + blksize);
|
b = (block *)((char *)b + blksize);
|
||||||
}
|
}
|
||||||
|
|
||||||
_numAvailable = _numBlocks;
|
_numAvailable = _numBlocks;
|
||||||
computeFullness();
|
computeFullness();
|
||||||
assert ((unsigned long) b <= hoardHeap::align (sizeof(superblock) + blksize * _numBlocks) + (unsigned long) this);
|
assert((unsigned long)b <= hoardHeap::align(sizeof(superblock) + blksize * _numBlocks)
|
||||||
|
+ (unsigned long)this);
|
||||||
|
|
||||||
hoardLockInit(_upLock, "hoard superblock");
|
hoardLockInit(_upLock, "hoard superblock");
|
||||||
}
|
}
|
||||||
|
|
||||||
superblock * superblock::makeSuperblock (int sizeclass,
|
|
||||||
processHeap * pHeap)
|
superblock *
|
||||||
|
superblock::makeSuperblock(int sizeclass, processHeap * pHeap)
|
||||||
{
|
{
|
||||||
// We need to get more memory.
|
// We need to get more memory.
|
||||||
|
|
||||||
@@ -99,16 +99,18 @@ superblock * superblock::makeSuperblock (int sizeclass,
|
|||||||
unsigned long moreMemory;
|
unsigned long moreMemory;
|
||||||
if (numBlocks > 1) {
|
if (numBlocks > 1) {
|
||||||
moreMemory = hoardHeap::SUPERBLOCK_SIZE;
|
moreMemory = hoardHeap::SUPERBLOCK_SIZE;
|
||||||
assert (moreMemory >= hoardHeap::align(sizeof(superblock) + (hoardHeap::align (sizeof(block) + hoardHeap::sizeFromClass(sizeclass))) * numBlocks));
|
assert(moreMemory >= hoardHeap::align(sizeof(superblock)
|
||||||
|
+ (hoardHeap::align(sizeof(block)
|
||||||
|
+ hoardHeap::sizeFromClass(sizeclass))) * numBlocks));
|
||||||
|
|
||||||
// Get some memory from the process heap.
|
// Get some memory from the process heap.
|
||||||
buf = (char *)pHeap->getSuperblockBuffer();
|
buf = (char *)pHeap->getSuperblockBuffer();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// One object.
|
// One object.
|
||||||
assert(numBlocks == 1);
|
assert(numBlocks == 1);
|
||||||
|
|
||||||
size_t blksize = hoardHeap::align (sizeof(block) + hoardHeap::sizeFromClass(sizeclass));
|
size_t blksize = hoardHeap::align(sizeof(block)
|
||||||
|
+ hoardHeap::sizeFromClass(sizeclass));
|
||||||
moreMemory = hoardHeap::align(sizeof(superblock) + blksize);
|
moreMemory = hoardHeap::align(sizeof(superblock) + blksize);
|
||||||
|
|
||||||
// Get space from the system.
|
// Get space from the system.
|
||||||
@@ -116,9 +118,9 @@ superblock * superblock::makeSuperblock (int sizeclass,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Make sure that we actually got the memory.
|
// Make sure that we actually got the memory.
|
||||||
if (buf == NULL) {
|
if (buf == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
buf = (char *)hoardHeap::align((unsigned long)buf);
|
buf = (char *)hoardHeap::align((unsigned long)buf);
|
||||||
|
|
||||||
// Make sure this buffer is double-word aligned.
|
// Make sure this buffer is double-word aligned.
|
||||||
@@ -126,7 +128,5 @@ superblock * superblock::makeSuperblock (int sizeclass,
|
|||||||
assert((((unsigned long)buf) & hoardHeap::ALIGNMENT_MASK) == 0);
|
assert((((unsigned long)buf) & hoardHeap::ALIGNMENT_MASK) == 0);
|
||||||
|
|
||||||
// Instantiate the new superblock in the buffer.
|
// Instantiate the new superblock in the buffer.
|
||||||
superblock * sb = new (buf) superblock (numBlocks, sizeclass, NULL);
|
return new(buf) superblock(numBlocks, sizeclass, NULL);
|
||||||
|
|
||||||
return sb;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
The superblock class controls a number of blocks (which are
|
The superblock class controls a number of blocks (which are
|
||||||
allocatable units of memory).
|
allocatable units of memory).
|
||||||
------------------------------------------------------------------------
|
------------------------------------------------------------------------
|
||||||
@(#) $Id: superblock.h,v 1.1 2002/10/05 17:13:30 axeld Exp $
|
@(#) $Id$
|
||||||
------------------------------------------------------------------------
|
------------------------------------------------------------------------
|
||||||
Emery Berger | <http://www.cs.utexas.edu/users/emery>
|
Emery Berger | <http://www.cs.utexas.edu/users/emery>
|
||||||
Department of Computer Sciences | <http://www.cs.utexas.edu>
|
Department of Computer Sciences | <http://www.cs.utexas.edu>
|
||||||
@@ -44,21 +44,18 @@
|
|||||||
#include "arch-specific.h"
|
#include "arch-specific.h"
|
||||||
#include "block.h"
|
#include "block.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
class hoardHeap; // forward declaration
|
class hoardHeap; // forward declaration
|
||||||
class processHeap; // forward declaration
|
class processHeap; // forward declaration
|
||||||
|
|
||||||
class superblock {
|
class superblock {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// Construct a superblock for a given size class and set the heap
|
// Construct a superblock for a given size class and set the heap
|
||||||
// owner.
|
// owner.
|
||||||
superblock (int numblocks,
|
superblock(int numblocks, int sizeclass, hoardHeap *owner);
|
||||||
int sizeclass,
|
~superblock(void) {}
|
||||||
hoardHeap * owner);
|
|
||||||
|
|
||||||
~superblock (void)
|
|
||||||
{}
|
|
||||||
|
|
||||||
// Make (allocate or re-use) a superblock for a given size class.
|
// Make (allocate or re-use) a superblock for a given size class.
|
||||||
static superblock *makeSuperblock(int sizeclass, processHeap *pHeap);
|
static superblock *makeSuperblock(int sizeclass, processHeap *pHeap);
|
||||||
@@ -111,16 +108,19 @@ public:
|
|||||||
// does it have the right magic number?)
|
// does it have the right magic number?)
|
||||||
inline int isValid(void);
|
inline int isValid(void);
|
||||||
|
|
||||||
void upLock (void) {
|
void
|
||||||
|
upLock(void)
|
||||||
|
{
|
||||||
hoardLock(_upLock);
|
hoardLock(_upLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void upUnlock (void) {
|
void
|
||||||
|
upUnlock(void)
|
||||||
|
{
|
||||||
hoardUnlock(_upLock);
|
hoardUnlock(_upLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// Disable copying and assignment.
|
// Disable copying and assignment.
|
||||||
|
|
||||||
superblock(const superblock &);
|
superblock(const superblock &);
|
||||||
@@ -147,12 +147,12 @@ private:
|
|||||||
|
|
||||||
// We insert a cache pad here to prevent false sharing with the
|
// We insert a cache pad here to prevent false sharing with the
|
||||||
// first block (which immediately follows the superblock).
|
// first block (which immediately follows the superblock).
|
||||||
|
|
||||||
double _pad[CACHE_LINE / sizeof(double)];
|
double _pad[CACHE_LINE / sizeof(double)];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
hoardHeap * superblock::getOwner (void)
|
hoardHeap *
|
||||||
|
superblock::getOwner(void)
|
||||||
{
|
{
|
||||||
assert(isValid());
|
assert(isValid());
|
||||||
hoardHeap *o = _owner;
|
hoardHeap *o = _owner;
|
||||||
@@ -160,14 +160,16 @@ hoardHeap * superblock::getOwner (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void superblock::setOwner (hoardHeap * o)
|
void
|
||||||
|
superblock::setOwner(hoardHeap *o)
|
||||||
{
|
{
|
||||||
assert(isValid());
|
assert(isValid());
|
||||||
_owner = o;
|
_owner = o;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
block * superblock::getBlock (void)
|
block *
|
||||||
|
superblock::getBlock(void)
|
||||||
{
|
{
|
||||||
assert(isValid());
|
assert(isValid());
|
||||||
// Pop off a block from this superblock's freelist,
|
// Pop off a block from this superblock's freelist,
|
||||||
@@ -177,6 +179,7 @@ block * superblock::getBlock (void)
|
|||||||
assert(getNumAvailable() == 0);
|
assert(getNumAvailable() == 0);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(getNumAvailable() > 0);
|
assert(getNumAvailable() > 0);
|
||||||
block *b = _freeList;
|
block *b = _freeList;
|
||||||
_freeList = _freeList->getNext();
|
_freeList = _freeList->getNext();
|
||||||
@@ -185,12 +188,12 @@ block * superblock::getBlock (void)
|
|||||||
b->setNext(NULL);
|
b->setNext(NULL);
|
||||||
|
|
||||||
computeFullness();
|
computeFullness();
|
||||||
|
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void superblock::putBlock (block * b)
|
void
|
||||||
|
superblock::putBlock(block *b)
|
||||||
{
|
{
|
||||||
assert(isValid());
|
assert(isValid());
|
||||||
// Push a block onto the superblock's freelist.
|
// Push a block onto the superblock's freelist.
|
||||||
@@ -203,41 +206,49 @@ void superblock::putBlock (block * b)
|
|||||||
computeFullness();
|
computeFullness();
|
||||||
}
|
}
|
||||||
|
|
||||||
int superblock::getNumAvailable (void)
|
|
||||||
|
int
|
||||||
|
superblock::getNumAvailable(void)
|
||||||
{
|
{
|
||||||
assert(isValid());
|
assert(isValid());
|
||||||
return _numAvailable;
|
return _numAvailable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int superblock::getNumBlocks (void)
|
int
|
||||||
|
superblock::getNumBlocks(void)
|
||||||
{
|
{
|
||||||
assert(isValid());
|
assert(isValid());
|
||||||
return _numBlocks;
|
return _numBlocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int superblock::getBlockSizeClass (void)
|
int
|
||||||
|
superblock::getBlockSizeClass(void)
|
||||||
{
|
{
|
||||||
assert(isValid());
|
assert(isValid());
|
||||||
return _sizeClass;
|
return _sizeClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
superblock * const superblock::getNext (void)
|
superblock * const
|
||||||
|
superblock::getNext(void)
|
||||||
{
|
{
|
||||||
assert(isValid());
|
assert(isValid());
|
||||||
return _next;
|
return _next;
|
||||||
}
|
}
|
||||||
|
|
||||||
superblock * const superblock::getPrev (void)
|
superblock * const
|
||||||
|
superblock::getPrev(void)
|
||||||
{
|
{
|
||||||
assert(isValid());
|
assert(isValid());
|
||||||
return _prev;
|
return _prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void superblock::insertBefore (superblock * nextSb) {
|
void
|
||||||
|
superblock::insertBefore(superblock * nextSb)
|
||||||
|
{
|
||||||
assert(isValid());
|
assert(isValid());
|
||||||
// Insert this superblock before the next one (nextSb).
|
// Insert this superblock before the next one (nextSb).
|
||||||
assert(nextSb != this);
|
assert(nextSb != this);
|
||||||
@@ -249,20 +260,22 @@ void superblock::insertBefore (superblock * nextSb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void superblock::remove (void) {
|
void
|
||||||
|
superblock::remove(void)
|
||||||
|
{
|
||||||
// Remove this superblock from a doubly-linked list.
|
// Remove this superblock from a doubly-linked list.
|
||||||
if (_next) {
|
if (_next)
|
||||||
_next->_prev = _prev;
|
_next->_prev = _prev;
|
||||||
}
|
if (_prev)
|
||||||
if (_prev) {
|
|
||||||
_prev->_next = _next;
|
_prev->_next = _next;
|
||||||
}
|
|
||||||
_prev = NULL;
|
_prev = NULL;
|
||||||
_next = NULL;
|
_next = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int superblock::isValid (void)
|
int
|
||||||
|
superblock::isValid(void)
|
||||||
{
|
{
|
||||||
assert(_numBlocks > 0);
|
assert(_numBlocks > 0);
|
||||||
assert(_numAvailable <= _numBlocks);
|
assert(_numAvailable <= _numBlocks);
|
||||||
@@ -271,17 +284,22 @@ int superblock::isValid (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void superblock::computeFullness (void)
|
void
|
||||||
|
superblock::computeFullness(void)
|
||||||
{
|
{
|
||||||
assert(isValid());
|
assert(isValid());
|
||||||
_fullness = (((SUPERBLOCK_FULLNESS_GROUP - 1)
|
_fullness = (((SUPERBLOCK_FULLNESS_GROUP - 1)
|
||||||
* (getNumBlocks() - getNumAvailable())) / getNumBlocks());
|
* (getNumBlocks() - getNumAvailable())) / getNumBlocks());
|
||||||
}
|
}
|
||||||
|
|
||||||
int superblock::getFullness (void)
|
|
||||||
|
int
|
||||||
|
superblock::getFullness(void)
|
||||||
{
|
{
|
||||||
assert(isValid());
|
assert(isValid());
|
||||||
return _fullness;
|
return _fullness;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
#endif // _SUPERBLOCK_H_
|
#endif // _SUPERBLOCK_H_
|
||||||
|
|||||||
@@ -26,10 +26,13 @@
|
|||||||
#include "threadheap.h"
|
#include "threadheap.h"
|
||||||
#include "processheap.h"
|
#include "processheap.h"
|
||||||
|
|
||||||
|
using namespace BPrivate;
|
||||||
|
|
||||||
|
|
||||||
threadHeap::threadHeap(void)
|
threadHeap::threadHeap(void)
|
||||||
:_pHeap(0)
|
:_pHeap(0)
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// malloc (sz):
|
// malloc (sz):
|
||||||
@@ -38,7 +41,8 @@ threadHeap::threadHeap (void)
|
|||||||
// side effects: allocates a block from a superblock;
|
// side effects: allocates a block from a superblock;
|
||||||
// may call sbrk() (via makeSuperblock).
|
// may call sbrk() (via makeSuperblock).
|
||||||
|
|
||||||
void * threadHeap::malloc (const size_t size)
|
void *
|
||||||
|
threadHeap::malloc(const size_t size)
|
||||||
{
|
{
|
||||||
const int sizeclass = sizeClass(size);
|
const int sizeclass = sizeClass(size);
|
||||||
block *b = NULL;
|
block *b = NULL;
|
||||||
@@ -52,7 +56,6 @@ void * threadHeap::malloc (const size_t size)
|
|||||||
superblock *sb = findAvailableSuperblock(sizeclass, b, _pHeap);
|
superblock *sb = findAvailableSuperblock(sizeclass, b, _pHeap);
|
||||||
|
|
||||||
if (sb == NULL) {
|
if (sb == NULL) {
|
||||||
|
|
||||||
// We don't have memory locally.
|
// We don't have memory locally.
|
||||||
// Try to get more from the process heap.
|
// Try to get more from the process heap.
|
||||||
|
|
||||||
@@ -71,14 +74,15 @@ void * threadHeap::malloc (const size_t size)
|
|||||||
#if HEAP_LOG
|
#if HEAP_LOG
|
||||||
// Record the memory allocation.
|
// Record the memory allocation.
|
||||||
MemoryRequest m;
|
MemoryRequest m;
|
||||||
m.allocate ((int) sb->getNumBlocks() * (int) sizeFromClass(sb->getBlockSizeClass()));
|
m.allocate((int)sb->getNumBlocks() *
|
||||||
|
(int)sizeFromClass(sb->getBlockSizeClass()));
|
||||||
_pHeap->getLog(getIndex()).append(m);
|
_pHeap->getLog(getIndex()).append(m);
|
||||||
#endif
|
#endif
|
||||||
#if HEAP_FRAG_STATS
|
#if HEAP_FRAG_STATS
|
||||||
_pHeap->setAllocated (0, sb->getNumBlocks() * sizeFromClass(sb->getBlockSizeClass()));
|
_pHeap->setAllocated(0,
|
||||||
|
sb->getNumBlocks() * sizeFromClass(sb->getBlockSizeClass()));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get a block from the superblock.
|
// Get a block from the superblock.
|
||||||
b = sb->getBlock();
|
b = sb->getBlock();
|
||||||
assert(b != NULL);
|
assert(b != NULL);
|
||||||
|
|||||||
@@ -26,6 +26,8 @@
|
|||||||
|
|
||||||
#include "heap.h"
|
#include "heap.h"
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
class processHeap; // forward declaration
|
class processHeap; // forward declaration
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -33,9 +35,7 @@ class processHeap; // forward declaration
|
|||||||
//
|
//
|
||||||
|
|
||||||
class threadHeap : public hoardHeap {
|
class threadHeap : public hoardHeap {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
threadHeap(void);
|
threadHeap(void);
|
||||||
|
|
||||||
// Memory allocation routines.
|
// Memory allocation routines.
|
||||||
@@ -49,7 +49,6 @@ public:
|
|||||||
inline void setpHeap(processHeap *p);
|
inline void setpHeap(processHeap *p);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// Prevent copying and assignment.
|
// Prevent copying and assignment.
|
||||||
threadHeap(const threadHeap &);
|
threadHeap(const threadHeap &);
|
||||||
const threadHeap &operator=(const threadHeap &);
|
const threadHeap &operator=(const threadHeap &);
|
||||||
@@ -64,8 +63,8 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void * threadHeap::memalign (size_t alignment,
|
void *
|
||||||
size_t size)
|
threadHeap::memalign(size_t alignment, size_t size)
|
||||||
{
|
{
|
||||||
// Calculate the amount of space we need
|
// Calculate the amount of space we need
|
||||||
// to satisfy the alignment requirements.
|
// to satisfy the alignment requirements.
|
||||||
@@ -74,13 +73,11 @@ void * threadHeap::memalign (size_t alignment,
|
|||||||
|
|
||||||
// If the alignment is less than the required alignment,
|
// If the alignment is less than the required alignment,
|
||||||
// just call malloc.
|
// just call malloc.
|
||||||
if (alignment <= ALIGNMENT) {
|
if (alignment <= ALIGNMENT)
|
||||||
return this->malloc(size);
|
return this->malloc(size);
|
||||||
}
|
|
||||||
|
|
||||||
if (alignment < sizeof(block)) {
|
if (alignment < sizeof(block))
|
||||||
alignment = sizeof(block);
|
alignment = sizeof(block);
|
||||||
}
|
|
||||||
|
|
||||||
// Alignment must be a power of two!
|
// Alignment must be a power of two!
|
||||||
assert((alignment & (alignment - 1)) == 0);
|
assert((alignment & (alignment - 1)) == 0);
|
||||||
@@ -96,18 +93,15 @@ void * threadHeap::memalign (size_t alignment,
|
|||||||
// ptr is already aligned, so return it.
|
// ptr is already aligned, so return it.
|
||||||
assert(((unsigned long) ptr % alignment) == 0);
|
assert(((unsigned long) ptr % alignment) == 0);
|
||||||
return ptr;
|
return ptr;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// Align ptr.
|
// Align ptr.
|
||||||
char * newptr = (char *)
|
char *newptr = (char *)(((unsigned long)ptr + alignment - 1) & -((long)alignment));
|
||||||
(((unsigned long) ptr + alignment - 1) & -((long) alignment));
|
|
||||||
|
|
||||||
// If there's not enough room for the block header, skip to the
|
// If there's not enough room for the block header, skip to the
|
||||||
// next aligned space within the block..
|
// next aligned space within the block..
|
||||||
if ((unsigned long) newptr - (unsigned long) ptr < sizeof(block)) {
|
if ((unsigned long)newptr - (unsigned long)ptr < sizeof(block))
|
||||||
newptr += alignment;
|
newptr += alignment;
|
||||||
}
|
|
||||||
assert(((unsigned long)newptr % alignment) == 0);
|
assert(((unsigned long)newptr % alignment) == 0);
|
||||||
|
|
||||||
// Copy the block from the start of the allocated memory.
|
// Copy the block from the start of the allocated memory.
|
||||||
@@ -117,7 +111,8 @@ void * threadHeap::memalign (size_t alignment,
|
|||||||
assert(b->getSuperblock()->isValid());
|
assert(b->getSuperblock()->isValid());
|
||||||
|
|
||||||
// Make sure there's enough room for the block header.
|
// Make sure there's enough room for the block header.
|
||||||
assert (((unsigned long) newptr - (unsigned long) ptr) >= sizeof(block));
|
assert(((unsigned long)newptr - (unsigned long)ptr) >=
|
||||||
|
sizeof(block));
|
||||||
|
|
||||||
block *p = ((block *)newptr - 1);
|
block *p = ((block *)newptr - 1);
|
||||||
|
|
||||||
@@ -134,21 +129,20 @@ void * threadHeap::memalign (size_t alignment,
|
|||||||
// Set the next pointer to point to b with the 1 bit set.
|
// Set the next pointer to point to b with the 1 bit set.
|
||||||
// When this block is freed, it will be treated specially.
|
// When this block is freed, it will be treated specially.
|
||||||
p->setNext((block *)((unsigned long)b | 1));
|
p->setNext((block *)((unsigned long)b | 1));
|
||||||
|
} else
|
||||||
} else {
|
|
||||||
assert(ptr != newptr);
|
assert(ptr != newptr);
|
||||||
}
|
|
||||||
|
|
||||||
assert (((unsigned long) ptr + newSize) >= ((unsigned long) newptr + size));
|
assert(((unsigned long)ptr + newSize) >=
|
||||||
|
((unsigned long)newptr + size));
|
||||||
return newptr;
|
return newptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
size_t threadHeap::objectSize (void * ptr)
|
size_t
|
||||||
|
threadHeap::objectSize(void *ptr)
|
||||||
{
|
{
|
||||||
// Find the superblock pointer.
|
// Find the superblock pointer.
|
||||||
|
|
||||||
block *b = ((block *)ptr - 1);
|
block *b = ((block *)ptr - 1);
|
||||||
assert(b->isValid());
|
assert(b->isValid());
|
||||||
superblock *sb = b->getSuperblock();
|
superblock *sb = b->getSuperblock();
|
||||||
@@ -164,5 +158,6 @@ void threadHeap::setpHeap (processHeap * p)
|
|||||||
_pHeap = p;
|
_pHeap = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // _THREADHEAP_H_
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
#endif // _THREADHEAP_H_
|
||||||
|
|||||||
@@ -23,11 +23,14 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "threadheap.h"
|
#include "threadheap.h"
|
||||||
#include "processheap.h"
|
#include "processheap.h"
|
||||||
#include "arch-specific.h"
|
#include "arch-specific.h"
|
||||||
|
|
||||||
|
using namespace BPrivate;
|
||||||
|
|
||||||
|
|
||||||
inline static processHeap *
|
inline static processHeap *
|
||||||
getAllocator(void)
|
getAllocator(void)
|
||||||
@@ -38,21 +41,7 @@ getAllocator(void)
|
|||||||
return theAllocator;
|
return theAllocator;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define HOARD_MALLOC(x) malloc(x)
|
#if 0
|
||||||
#define HOARD_FREE(x) free(x)
|
|
||||||
#define HOARD_REALLOC(x,y) realloc(x,y)
|
|
||||||
#define HOARD_CALLOC(x,y) calloc(x,y)
|
|
||||||
#define HOARD_MEMALIGN(x,y) memalign(x,y)
|
|
||||||
#define HOARD_VALLOC(x) valloc(x)
|
|
||||||
|
|
||||||
extern "C" void * HOARD_MALLOC(size_t);
|
|
||||||
extern "C" void HOARD_FREE(void *);
|
|
||||||
extern "C" void * HOARD_REALLOC(void *, size_t);
|
|
||||||
extern "C" void * HOARD_CALLOC(size_t, size_t);
|
|
||||||
extern "C" void * HOARD_MEMALIGN(size_t, size_t);
|
|
||||||
extern "C" void * HOARD_VALLOC(size_t);
|
|
||||||
|
|
||||||
|
|
||||||
void * operator new (size_t size)
|
void * operator new (size_t size)
|
||||||
{
|
{
|
||||||
return HOARD_MALLOC (size);
|
return HOARD_MALLOC (size);
|
||||||
@@ -80,6 +69,7 @@ void operator delete[] (void * ptr)
|
|||||||
{
|
{
|
||||||
HOARD_FREE (ptr);
|
HOARD_FREE (ptr);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
extern "C" void *
|
extern "C" void *
|
||||||
@@ -133,7 +123,7 @@ extern "C" void *
|
|||||||
realloc(void *ptr, size_t sz)
|
realloc(void *ptr, size_t sz)
|
||||||
{
|
{
|
||||||
if (ptr == NULL)
|
if (ptr == NULL)
|
||||||
return HOARD_MALLOC (sz);
|
return malloc(sz);
|
||||||
|
|
||||||
if (sz == 0) {
|
if (sz == 0) {
|
||||||
free(ptr);
|
free(ptr);
|
||||||
@@ -148,7 +138,6 @@ realloc(void *ptr, size_t sz)
|
|||||||
return ptr;
|
return ptr;
|
||||||
|
|
||||||
// Allocate a new block of size sz.
|
// Allocate a new block of size sz.
|
||||||
|
|
||||||
void *buffer = malloc(sz);
|
void *buffer = malloc(sz);
|
||||||
|
|
||||||
// Copy the contents of the original object
|
// Copy the contents of the original object
|
||||||
@@ -158,7 +147,6 @@ realloc(void *ptr, size_t sz)
|
|||||||
memcpy(buffer, ptr, minSize);
|
memcpy(buffer, ptr, minSize);
|
||||||
|
|
||||||
// Free the old block.
|
// Free the old block.
|
||||||
|
|
||||||
free(ptr);
|
free(ptr);
|
||||||
|
|
||||||
// Return a pointer to the new one.
|
// Return a pointer to the new one.
|
||||||
|
|||||||
Reference in New Issue
Block a user