| 1155 | |
| 1156 | #if defined(_WIN32) && (MI_INTPTR_SIZE >= 8) |
| 1157 | static void* mi_os_alloc_huge_os_pagesx(void* addr, size_t size, int numa_node) |
| 1158 | { |
| 1159 | mi_assert_internal(size%MI_GiB == 0); |
| 1160 | mi_assert_internal(addr != NULL); |
| 1161 | const DWORD flags = MEM_LARGE_PAGES | MEM_COMMIT | MEM_RESERVE; |
| 1162 | |
| 1163 | mi_win_enable_large_os_pages(); |
| 1164 | |
| 1165 | MI_MEM_EXTENDED_PARAMETER params[3] = { {{0,0},{0}},{{0,0},{0}},{{0,0},{0}} }; |
| 1166 | // on modern Windows try use NtAllocateVirtualMemoryEx for 1GiB huge pages |
| 1167 | static bool mi_huge_pages_available = true; |
| 1168 | if (pNtAllocateVirtualMemoryEx != NULL && mi_huge_pages_available) { |
| 1169 | params[0].Type.Type = MiMemExtendedParameterAttributeFlags; |
| 1170 | params[0].Arg.ULong64 = MI_MEM_EXTENDED_PARAMETER_NONPAGED_HUGE; |
| 1171 | ULONG param_count = 1; |
| 1172 | if (numa_node >= 0) { |
| 1173 | param_count++; |
| 1174 | params[1].Type.Type = MiMemExtendedParameterNumaNode; |
| 1175 | params[1].Arg.ULong = (unsigned)numa_node; |
| 1176 | } |
| 1177 | SIZE_T psize = size; |
| 1178 | void* base = addr; |
| 1179 | NTSTATUS err = (*pNtAllocateVirtualMemoryEx)(GetCurrentProcess(), &base, &psize, flags, PAGE_READWRITE, params, param_count); |
| 1180 | if (err == 0 && base != NULL) { |
| 1181 | return base; |
| 1182 | } |
| 1183 | else { |
| 1184 | // fall back to regular large pages |
| 1185 | mi_huge_pages_available = false; // don't try further huge pages |
| 1186 | _mi_warning_message("unable to allocate using huge (1GiB) pages, trying large (2MiB) pages instead (status 0x%lx)\n", err); |
| 1187 | } |
| 1188 | } |
| 1189 | // on modern Windows try use VirtualAlloc2 for numa aware large OS page allocation |
| 1190 | if (pVirtualAlloc2 != NULL && numa_node >= 0) { |
| 1191 | params[0].Type.Type = MiMemExtendedParameterNumaNode; |
| 1192 | params[0].Arg.ULong = (unsigned)numa_node; |
| 1193 | return (*pVirtualAlloc2)(GetCurrentProcess(), addr, size, flags, PAGE_READWRITE, params, 1); |
| 1194 | } |
| 1195 | |
| 1196 | // otherwise use regular virtual alloc on older windows |
| 1197 | return VirtualAlloc(addr, size, flags, PAGE_READWRITE); |
| 1198 | } |
| 1199 | |
| 1200 | #elif defined(MI_OS_USE_MMAP) && (MI_INTPTR_SIZE >= 8) && !defined(__HAIKU__) |
| 1201 | #include <sys/syscall.h> |
no test coverage detected