#ifndef HOARD_HOARDHEAP_H
#define HOARD_HOARDHEAP_H
#include <assert.h>
#include "heaplayers.h"
using namespace HL;
#if defined(_WIN32)
#define SUPERBLOCK_SIZE 65536UL
#else
#define SUPERBLOCK_SIZE 262144UL
#endif
#define EMPTINESS_CLASSES 8
#include "thresholdheap.h"
#include "hoardmanager.h"
#include "addheaderheap.h"
#include "threadpoolheap.h"
#include "redirectfree.h"
#include "ignoreinvalidfree.h"
#include "conformantheap.h"
#include "hoardsuperblock.h"
#include "hoardsuperblockheader.h"
#include "lockmallocheap.h"
#include "alignedsuperblockheap.h"
#include "alignedmmap.h"
#include "globalheap.h"
#include "thresholdsegheap.h"
#include "geometricsizeclass.h"
#if defined(_WIN32)
typedef HL::WinLockType TheLockType;
#elif defined(__APPLE__)
typedef HL::MacLockType TheLockType;
#elif defined(__SVR4)
typedef HL::SpinLockType TheLockType;
#else
typedef HL::SpinLockType TheLockType;
#endif
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-variable"
#endif
namespace Hoard {
class MmapSource : public AlignedMmap<SUPERBLOCK_SIZE, TheLockType> {};
typedef GlobalHeap<SUPERBLOCK_SIZE, HoardSuperblockHeader, EMPTINESS_CLASSES, MmapSource, TheLockType>
TheGlobalHeap;
class hoardThresholdFunctionClass {
public:
inline static bool function (unsigned int u,
unsigned int a,
size_t objSize)
{
auto r = ((EMPTINESS_CLASSES * u) < ((EMPTINESS_CLASSES-1) * a)) && ((u < a - (2 * SUPERBLOCK_SIZE) / objSize));
return r;
}
};
class SmallHeap;
typedef HoardSuperblock<TheLockType, SUPERBLOCK_SIZE, SmallHeap, Hoard::HoardSuperblockHeader> SmallSuperblockType;
class SmallHeap :
public ConformantHeap<
HoardManager<AlignedSuperblockHeap<TheLockType, SUPERBLOCK_SIZE, MmapSource>,
TheGlobalHeap,
SmallSuperblockType,
EMPTINESS_CLASSES,
TheLockType,
hoardThresholdFunctionClass,
SmallHeap> >
{};
class BigHeap;
typedef HoardSuperblock<TheLockType,
SUPERBLOCK_SIZE,
BigHeap,
Hoard::HoardSuperblockHeader>
BigSuperblockType;
#if 0#else
class objectSource : public AddHeaderHeap<BigSuperblockType,
SUPERBLOCK_SIZE,
MmapSource> {};
typedef HL::ThreadHeap<64, HL::LockedHeap<TheLockType,
ThresholdSegHeap<25, 1048576, 80, GeometricSizeClass<20>::size2class,
GeometricSizeClass<20>::class2size,
GeometricSizeClass<20>::MaxObjectSize,
AdaptHeap<DLList, objectSource>,
objectSource> > >
bigHeapType;
#endif
class BigHeap : public bigHeapType {};
enum { BigObjectSize =
HL::bins<SmallSuperblockType::Header, SUPERBLOCK_SIZE>::BIG_OBJECT };
class PerThreadHoardHeap :
public RedirectFree<LockMallocHeap<SmallHeap>,
SmallSuperblockType> {
private:
void nothing() {
_dummy[0] = _dummy[0];
}
char _dummy[64];
};
template <int N, int NH>
class HoardHeap :
public HL::ANSIWrapper<
IgnoreInvalidFree<
HL::HybridHeap<Hoard::BigObjectSize,
ThreadPoolHeap<N, NH, Hoard::PerThreadHoardHeap>,
Hoard::BigHeap> > >
{
public:
enum { BIG_OBJECT = Hoard::BigObjectSize };
HoardHeap() {
enum { BIG_HEADERS = sizeof(Hoard::BigSuperblockType::Header),
SMALL_HEADERS = sizeof(Hoard::SmallSuperblockType::Header)};
static_assert(BIG_HEADERS == SMALL_HEADERS,
"Headers must be the same size.");
}
};
}
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
#endif