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:
Axel Dörfler
2005-03-22 22:59:41 +00:00
parent f05dec1ea0
commit f557016851
13 changed files with 1569 additions and 1449 deletions
@@ -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;
+53 -26
View File
@@ -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_
-1
View File
@@ -89,4 +89,3 @@ enum { SUPERBLOCK_FULLNESS_GROUP = 9 };
#endif // _CONFIG_H_ #endif // _CONFIG_H_
+102 -51
View File
@@ -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;
+66 -48
View File
@@ -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_
+24 -22
View File
@@ -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_
+23 -21
View File
@@ -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();
} }
}
+46 -31
View File
@@ -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_
+21 -21
View File
@@ -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;
} }
+50 -32
View File
@@ -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_
+10 -6
View File
@@ -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);
+18 -23
View File
@@ -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_
+6 -18
View File
@@ -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.