Skip to content

Instantly share code, notes, and snippets.

@TronicLabs
Forked from NickStrupat/virtual_memory.hpp
Created June 12, 2024 05:19
Show Gist options
  • Select an option

  • Save TronicLabs/fb873b4baf6fb54cc2ebaf40f6071cc6 to your computer and use it in GitHub Desktop.

Select an option

Save TronicLabs/fb873b4baf6fb54cc2ebaf40f6071cc6 to your computer and use it in GitHub Desktop.
#pragma once
#include <exception>
#include <windows.h>
struct win32_exception : std::exception
{
DWORD const last_error;
explicit win32_exception() : last_error(GetLastError()) {}
};
namespace cova::mem::raw
{
struct virtual_alloc_exception : win32_exception {};
struct virtual_alloc_reserve_exception final : virtual_alloc_exception {};
struct virtual_alloc_commit_exception final : virtual_alloc_exception {};
struct virtual_free_exception : win32_exception {};
struct virtual_alloc_decommit_exception final : virtual_free_exception {};
struct virtual_alloc_release_exception final : virtual_free_exception {};
void * reserve(size_t const size)
{
auto const address = VirtualAlloc(nullptr, size, MEM_RESERVE, PAGE_NOACCESS); // don't use MEM_TOP_DOWN (https://randomascii.wordpress.com/2011/08/05/making-virtualalloc-arbitrarily-slower/)
if (address == nullptr)
throw virtual_alloc_reserve_exception();
return address;
}
void commit(void * const reserved, size_t const size)
{
auto const result = VirtualAlloc(reserved, size, MEM_COMMIT, PAGE_READWRITE);
if (result == nullptr)
throw virtual_alloc_commit_exception();
}
void decommit(void * const committed)
{
auto const result = VirtualFree(committed, 0, MEM_DECOMMIT);
if (result == 0)
throw virtual_alloc_decommit_exception();
}
void release(void * const reserved)
{
auto const result = VirtualFree(reserved, 0, MEM_RELEASE);
if (result == 0)
throw virtual_alloc_release_exception();
}
/*
//https://stackoverflow.com/questions/30057381/c-porting-virtualfree-in-os-x
//to reserve virtual address space
//equivalent of VirtualAlloc(NULL, size, MEM_RESERVE, PAGE_NOACCESS)
void* ptr = mmap(NULL, size, PROT_NONE, (MAP_PRIVATE | MAP_ANON), -1, 0);
msync(ptr, size, (MS_SYNC | MS_INVALIDATE));
//to free ALL virtual address space
//equivalent of VirtualFree(addr, 0, MEM_RELEASE)
//where "size" is the size of the entire virtual address space and "addr" the starting address
msync(addr, size, MS_SYNC);
munmap(addr, size);
//to allocate physical memory
//equivalent of VirtualAlloc(addr, size, MEM_COMMIT, PAGE_READWRITE)
void* ptr = mmap(addr, size, (PROT_READ | PROT_WRITE), (MAP_FIXED | MAP_SHARED | MAP_ANON), -1, 0);
msync(addr, size, (MS_SYNC | MS_INVALIDATE));
void DecommitMemory(void* addr, size_t size)
{
// instead of unmapping the address, we're just gonna trick
// the TLB to mark this as a new mapped area which, due to
// demand paging, will not be committed until used.
mmap(addr, size, PROT_NONE, MAP_FIXED|MAP_PRIVATE|MAP_ANON, -1, 0);
msync(addr, size, MS_SYNC|MS_INVALIDATE);
}
*/
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment