4#include "virtual_memory.h"
10#include <mach/vm_statistics.h>
15#define MAP_ANONYMOUS MAP_ANON
17#define PAGE_READONLY PROT_READ
18#define PAGE_READWRITE (PROT_READ | PROT_WRITE)
19#define PAGE_EXECUTE_READ (PROT_READ | PROT_EXEC)
20#define PAGE_EXECUTE_READWRITE (PROT_READ | PROT_WRITE | PROT_EXEC)
21#if defined(__NetBSD__) && defined(PROT_MPROTECT)
22#define PAGE_MMAP_PROT (PAGE_READWRITE | PROT_MPROTECT(PROT_EXEC))
24#define PAGE_MMAP_PROT PAGE_READWRITE
28void* hashx_vm_alloc(
size_t bytes) {
31 mem = VirtualAlloc(NULL, bytes, MEM_COMMIT, PAGE_READWRITE);
33 mem = mmap(NULL, bytes, PAGE_MMAP_PROT, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
34 if (mem == MAP_FAILED)
40static inline bool page_protect(
void* ptr,
size_t bytes,
int rules) {
43 if (!VirtualProtect(ptr, bytes, (DWORD)rules, &oldp)) {
47 if (mprotect(ptr, bytes, rules) != 0)
53bool hashx_vm_rw(
void* ptr,
size_t bytes) {
54 return page_protect(ptr, bytes, PAGE_READWRITE);
57bool hashx_vm_rx(
void* ptr,
size_t bytes) {
58 return page_protect(ptr, bytes, PAGE_EXECUTE_READ);
61#ifdef EQUIX_SUPPORT_HUGEPAGES
65static bool set_privilege(
const char* pszPrivilege, BOOL bEnable) {
71 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES
72 | TOKEN_QUERY, &hToken))
75 if (!LookupPrivilegeValue(NULL, pszPrivilege, &tp.Privileges[0].Luid))
78 tp.PrivilegeCount = 1;
81 tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
83 tp.Privileges[0].Attributes = 0;
85 status = AdjustTokenPrivileges(hToken, FALSE, &tp, 0,
86 (PTOKEN_PRIVILEGES)NULL, 0);
87 error = GetLastError();
91 return status && (error == ERROR_SUCCESS);
95void* hashx_vm_alloc_huge(
size_t bytes) {
98 if (!set_privilege(
"SeLockMemoryPrivilege", 1)) {
101 SIZE_T page_min = GetLargePageMinimum();
103 mem = VirtualAlloc(NULL, ALIGN_SIZE(bytes, page_min), MEM_COMMIT
104 | MEM_RESERVE | MEM_LARGE_PAGES, PAGE_READWRITE);
111 mem = mmap(NULL, bytes, PAGE_READWRITE, MAP_PRIVATE | MAP_ANONYMOUS,
112 VM_FLAGS_SUPERPAGE_SIZE_2MB, 0);
113#elif defined(__FreeBSD__)
114 mem = mmap(NULL, bytes, PAGE_READWRITE, MAP_PRIVATE | MAP_ANONYMOUS
115 | MAP_ALIGNED_SUPER, -1, 0);
116#elif defined(__OpenBSD__) || defined(__NetBSD__)
120 mem = mmap(NULL, bytes, PAGE_READWRITE, MAP_PRIVATE | MAP_ANONYMOUS
121 | MAP_HUGETLB | MAP_POPULATE, -1, 0);
123 if (mem == MAP_FAILED) {
131void hashx_vm_free(
void* ptr,
size_t bytes) {
137 VirtualFree(ptr, 0, MEM_RELEASE);