-
-
Save TronicLabs/fb873b4baf6fb54cc2ebaf40f6071cc6 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #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