#ifndef HOARD_ALIGNEDMMAP_H
#define HOARD_ALIGNEDMMAP_H
#include "heaplayers.h"
#include "mmapalloc.h"
using namespace std;
using namespace HL;
namespace Hoard {
template <size_t Alignment,
class LockType>
class AlignedMmap;
template <size_t Alignment_>
class AlignedMmapInstance {
public:
AlignedMmapInstance()
: MyMap (16381) {}
enum { Alignment = Alignment_ };
void clear() {
}
inline void * malloc (size_t sz) {
sz = HL::align<HL::MmapWrapper::Size>(sz);
if ((size_t) HL::MmapWrapper::Alignment % (size_t) Alignment == 0) {
void * ptr = HL::MmapWrapper::map (sz);
MyMap.set (ptr, sz);
assert ((size_t) ptr % Alignment == 0);
return ptr;
}
void * ptr = nullptr;
ptr = HL::MmapWrapper::map (sz);
if ((size_t) ptr == HL::align<Alignment>((size_t) ptr)) {
MyMap.set (ptr, sz);
return ptr;
}
HL::MmapWrapper::unmap ((void *) ptr, sz);
return slowMap (sz);
}
inline void free (void * ptr) {
size_t requestedSize = getSize (ptr);
if (requestedSize == 0) {
return;
}
HL::MmapWrapper::unmap (ptr, requestedSize);
MyMap.erase (ptr);
}
inline size_t getSize (void * ptr) {
return MyMap.get (ptr);
}
private:
void * slowMap (size_t sz) {
void * ptr = reinterpret_cast<char *>(HL::MmapWrapper::map (sz + Alignment));
if (ptr == nullptr) {
return nullptr;
}
char * newptr = (char *) HL::align<Alignment>((size_t) ptr);
size_t prolog = (size_t) newptr - (size_t) ptr;
if (prolog > 0) {
HL::MmapWrapper::unmap (ptr, prolog);
}
size_t epilog = Alignment - prolog;
HL::MmapWrapper::unmap ((char *) newptr + sz, epilog);
MyMap.set (newptr, sz);
return newptr;
}
typedef void * keyType;
typedef size_t valType;
class SourceHeap : public HL::FreelistHeap<BumpAlloc<65536, MmapAlloc> > { };
typedef MyHashMap<keyType, valType, SourceHeap> mapType;
mapType MyMap;
};
template <size_t Alignment_,
class LockType>
class AlignedMmap :
public ExactlyOneHeap<LockedHeap<LockType, AlignedMmapInstance<Alignment_> > > {};
}
#endif