Listing 3: A Win32 version of NoSwapHeap
class PageTracker
{
public:
void addBlock(void* pmem, size_t numBytes, size_t pageSize);
template<class UnlockPageFunctor>
void removeBlock(void *pmem, size_t numBytes, size_t pageSize,
UnlockPageFunctor unlockPage);
};
class NoSwapHeap : public PageTracker
{
public:
static const DWORD flags_; // heap flags
static const DWORD initSize_; // initial heap size
static const DWORD maxSize_; // max heap size
NoSwapHeap() : heap_(0), pageSize_(0)
{
SYSTEM_INFO sysInfo;
GetSystemInfo(&sysInfo);
pageSize_ = sysInfo.dwPageSize;
heap_ = HeapCreate(flags_, initSize_, maxSize_);
if (!heap_)
{
throw std::runtime_error(getErrorMsg().c_str());
}
}
void* doAlloc(size_t numBytes, const void* hint)
{
void *pmem = HeapAlloc(heap_, flags_, numBytes);
if (!pmem)
{
throw std::bad_alloc();
}
if (!VirtualLock(pmem, numBytes))
{
std::string msg(getErrorMsg());
HeapFree(heap_, flags_, pmem);
throw std::bad_alloc();
}
addBlock(pmem, numBytes, pageSize_);
return pmem;
}
void doFree(void* pmem, size_t numBytes)
{
removeBlock(pmem, numBytes, pageSize_, VirtualUnlock);
HeapFree(heap_, flags_, pmem);
}
private:
std::string getErrorMsg();
DWORD pageSize_; // system page size
HANDLE heap_; // handle to the heap object
};