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
};