#ifndef _PROCESSHEAP_H_
#define _PROCESSHEAP_H_
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include "arch-specific.h"
#include "heap.h"
#if USE_PRIVATE_HEAPS
# include "privateheap.h"
# define HEAPTYPE privateHeap
#else
# define HEAPTYPE threadHeap
# include "threadheap.h"
#endif
#if HEAP_LOG
# include "memstat.h"
# include "log.h"
#endif
namespace BPrivate {
class processHeap : public hoardHeap {
public:
enum { REFILL_NUMBER_OF_SUPERBLOCKS = 16 };
processHeap();
~processHeap(void)
{
#if HEAP_STATS
stats();
#endif
}
void free(void *ptr);
void stats(void);
inline int getHeapIndex(void);
inline int getMaxThreadHeaps(void);
inline HEAPTYPE & getHeap(int i);
inline superblock *acquire(const int c, hoardHeap * dest);
inline char *getSuperblockBuffer(void);
inline void release(superblock * sb);
#if HEAP_LOG
inline Log < MemoryRequest > &getLog(int i);
#endif
#if HEAP_FRAG_STATS
void setAllocated(int requestedSize, int actualSize);
void setDeallocated(int requestedSize, int actualSize);
inline int getFragmentation(void);
int
getMaxAllocated(void)
{
return _maxAllocated;
}
int
getInUseAtMaxAllocated(void)
{
return _inUseAtMaxAllocated;
}
int
getMaxRequested(void)
{
return _maxRequested;
}
#endif
private:
void
lock(void)
{
hoardHeap::lock();
}
void
unlock(void)
{
hoardHeap::unlock();
}
processHeap(const processHeap &);
const processHeap & operator=(const processHeap &);
HEAPTYPE* theap;
#if HEAP_FRAG_STATS
int _currentAllocated;
int _currentRequested;
int _maxAllocated;
int _maxRequested;
int _inUseAtMaxAllocated;
int _fragmentation;
hoardLockType _statsLock;
#endif
#if HEAP_LOG
Log < MemoryRequest >* _log;
#endif
hoardLockType _bufferLock;
char *_buffer;
int _bufferCount;
};
HEAPTYPE &
processHeap::getHeap(int i)
{
assert(theap != NULL);
assert(i >= 0);
assert(i < fMaxThreadHeaps);
return theap[i];
}
#if HEAP_LOG
Log<MemoryRequest > &
processHeap::getLog(int i)
{
assert(_log != NULL);
assert(i >= 0);
assert(i < fMaxThreadHeaps + 1);
return _log[i];
}
#endif
int
processHeap::getHeapIndex(void)
{
int tid = find_thread(NULL) & _numProcessorsMask;
assert(tid < fMaxThreadHeaps);
return tid;
}
int
processHeap::getMaxThreadHeaps(void)
{
return fMaxThreadHeaps;
}
superblock *
processHeap::acquire(const int sizeclass, hoardHeap * dest)
{
lock();
superblock *maxSb = removeMaxSuperblock(sizeclass);
if (maxSb)
maxSb->setOwner(dest);
unlock();
return maxSb;
}
inline char *
processHeap::getSuperblockBuffer(void)
{
char *buf;
hoardLock(_bufferLock);
if (_bufferCount == 0) {
_buffer = (char *)hoardSbrk(SUPERBLOCK_SIZE
* REFILL_NUMBER_OF_SUPERBLOCKS);
_bufferCount = REFILL_NUMBER_OF_SUPERBLOCKS;
}
buf = _buffer;
_buffer += SUPERBLOCK_SIZE;
_bufferCount--;
hoardUnlock(_bufferLock);
return buf;
}
void
processHeap::release(superblock *sb)
{
assert(EMPTY_FRACTION * sb->getNumAvailable() > sb->getNumBlocks());
lock();
insertSuperblock(sb->getBlockSizeClass(), sb, this);
unlock();
}
}
#endif