Skip to content

Commit 99ed3ea

Browse files
committed
enable building for xbox, based on pr #1084 by @maxbachmann
1 parent fda68e5 commit 99ed3ea

File tree

1 file changed

+36
-12
lines changed

1 file changed

+36
-12
lines changed

src/prim/windows/prim.c

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ terms of the MIT license. A copy of the license can be found in the file
1212
#include "mimalloc/prim.h"
1313
#include <stdio.h> // fputs, stderr
1414

15+
// xbox has no console IO
16+
#if !defined(WINAPI_FAMILY_PARTITION) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM)
17+
#define MI_HAS_CONSOLE_IO
18+
#endif
1519

1620
//---------------------------------------------
1721
// Dynamically bind Windows API points for portability
@@ -45,22 +49,30 @@ typedef struct MI_MEM_ADDRESS_REQUIREMENTS_S {
4549
#define MI_MEM_EXTENDED_PARAMETER_NONPAGED_HUGE 0x00000010
4650

4751
#include <winternl.h>
48-
typedef PVOID (__stdcall *PVirtualAlloc2)(HANDLE, PVOID, SIZE_T, ULONG, ULONG, MI_MEM_EXTENDED_PARAMETER*, ULONG);
49-
typedef NTSTATUS (__stdcall *PNtAllocateVirtualMemoryEx)(HANDLE, PVOID*, SIZE_T*, ULONG, ULONG, MI_MEM_EXTENDED_PARAMETER*, ULONG);
52+
typedef PVOID (__stdcall *PVirtualAlloc2)(HANDLE, PVOID, SIZE_T, ULONG, ULONG, MI_MEM_EXTENDED_PARAMETER*, ULONG);
53+
typedef LONG (__stdcall *PNtAllocateVirtualMemoryEx)(HANDLE, PVOID*, SIZE_T*, ULONG, ULONG, MI_MEM_EXTENDED_PARAMETER*, ULONG); // avoid NTSTATUS as it is not defined on xbox (pr #1084)
5054
static PVirtualAlloc2 pVirtualAlloc2 = NULL;
5155
static PNtAllocateVirtualMemoryEx pNtAllocateVirtualMemoryEx = NULL;
5256

53-
// Similarly, GetNumaProcessorNodeEx is only supported since Windows 7
57+
// Similarly, GetNumaProcessorNodeEx is only supported since Windows 7 (and GetNumaNodeProcessorMask is not supported on xbox)
5458
typedef struct MI_PROCESSOR_NUMBER_S { WORD Group; BYTE Number; BYTE Reserved; } MI_PROCESSOR_NUMBER;
5559

5660
typedef VOID (__stdcall *PGetCurrentProcessorNumberEx)(MI_PROCESSOR_NUMBER* ProcNumber);
5761
typedef BOOL (__stdcall *PGetNumaProcessorNodeEx)(MI_PROCESSOR_NUMBER* Processor, PUSHORT NodeNumber);
5862
typedef BOOL (__stdcall* PGetNumaNodeProcessorMaskEx)(USHORT Node, PGROUP_AFFINITY ProcessorMask);
5963
typedef BOOL (__stdcall *PGetNumaProcessorNode)(UCHAR Processor, PUCHAR NodeNumber);
64+
typedef BOOL (__stdcall* PGetNumaNodeProcessorMask)(UCHAR Node, PULONGLONG ProcessorMask);
65+
typedef BOOL (__stdcall* PGetNumaHighestNodeNumber)(PULONG Node);
6066
static PGetCurrentProcessorNumberEx pGetCurrentProcessorNumberEx = NULL;
6167
static PGetNumaProcessorNodeEx pGetNumaProcessorNodeEx = NULL;
6268
static PGetNumaNodeProcessorMaskEx pGetNumaNodeProcessorMaskEx = NULL;
6369
static PGetNumaProcessorNode pGetNumaProcessorNode = NULL;
70+
static PGetNumaNodeProcessorMask pGetNumaNodeProcessorMask = NULL;
71+
static PGetNumaHighestNodeNumber pGetNumaHighestNodeNumber = NULL;
72+
73+
// Not available on xbox
74+
typedef SIZE_T(__stdcall* PGetLargePageMinimum)(VOID);
75+
static PGetLargePageMinimum pGetLargePageMinimum = NULL;
6476

6577
// Available after Windows XP
6678
typedef BOOL (__stdcall *PGetPhysicallyInstalledSystemMemory)( PULONGLONG TotalMemoryInKilobytes );
@@ -74,6 +86,7 @@ static bool win_enable_large_os_pages(size_t* large_page_size)
7486
static bool large_initialized = false;
7587
if (large_initialized) return (_mi_os_large_page_size() > 0);
7688
large_initialized = true;
89+
if (pGetLargePageMinimum==NULL) return false; // no large page support (xbox etc.)
7790

7891
// Try to see if large OS pages are supported
7992
// To use large pages on Windows, we first need access permission
@@ -92,8 +105,8 @@ static bool win_enable_large_os_pages(size_t* large_page_size)
92105
if (ok) {
93106
err = GetLastError();
94107
ok = (err == ERROR_SUCCESS);
95-
if (ok && large_page_size != NULL) {
96-
*large_page_size = GetLargePageMinimum();
108+
if (ok && large_page_size != NULL && pGetLargePageMinimum != NULL) {
109+
*large_page_size = (*pGetLargePageMinimum)();
97110
}
98111
}
99112
}
@@ -149,6 +162,9 @@ void _mi_prim_mem_init( mi_os_mem_config_t* config )
149162
pGetNumaProcessorNodeEx = (PGetNumaProcessorNodeEx)(void (*)(void))GetProcAddress(hDll, "GetNumaProcessorNodeEx");
150163
pGetNumaNodeProcessorMaskEx = (PGetNumaNodeProcessorMaskEx)(void (*)(void))GetProcAddress(hDll, "GetNumaNodeProcessorMaskEx");
151164
pGetNumaProcessorNode = (PGetNumaProcessorNode)(void (*)(void))GetProcAddress(hDll, "GetNumaProcessorNode");
165+
pGetNumaNodeProcessorMask = (PGetNumaNodeProcessorMask)(void (*)(void))GetProcAddress(hDll, "GetNumaNodeProcessorMask");
166+
pGetNumaHighestNodeNumber = (PGetNumaHighestNodeNumber)(void (*)(void))GetProcAddress(hDll, "GetNumaHighestNodeNumber");
167+
pGetLargePageMinimum = (PGetLargePageMinimum)(void (*)(void))GetProcAddress(hDll, "GetLargePageMinimum");
152168
// Get physical memory (not available on XP, so check dynamically)
153169
PGetPhysicallyInstalledSystemMemory pGetPhysicallyInstalledSystemMemory = (PGetPhysicallyInstalledSystemMemory)(void (*)(void))GetProcAddress(hDll,"GetPhysicallyInstalledSystemMemory");
154170
if (pGetPhysicallyInstalledSystemMemory != NULL) {
@@ -388,7 +404,7 @@ static void* _mi_prim_alloc_huge_os_pagesx(void* hint_addr, size_t size, int num
388404
}
389405
SIZE_T psize = size;
390406
void* base = hint_addr;
391-
NTSTATUS err = (*pNtAllocateVirtualMemoryEx)(GetCurrentProcess(), &base, &psize, flags, PAGE_READWRITE, params, param_count);
407+
LONG err = (*pNtAllocateVirtualMemoryEx)(GetCurrentProcess(), &base, &psize, flags, PAGE_READWRITE, params, param_count);
392408
if (err == 0 && base != NULL) {
393409
return base;
394410
}
@@ -442,9 +458,11 @@ size_t _mi_prim_numa_node(void) {
442458

443459
size_t _mi_prim_numa_node_count(void) {
444460
ULONG numa_max = 0;
445-
GetNumaHighestNodeNumber(&numa_max);
461+
if (pGetNumaHighestNodeNumber!=NULL) {
462+
(*pGetNumaHighestNodeNumber)(&numa_max);
463+
}
446464
// find the highest node number that has actual processors assigned to it. Issue #282
447-
while(numa_max > 0) {
465+
while (numa_max > 0) {
448466
if (pGetNumaNodeProcessorMaskEx != NULL) {
449467
// Extended API is supported
450468
GROUP_AFFINITY affinity;
@@ -455,8 +473,10 @@ size_t _mi_prim_numa_node_count(void) {
455473
else {
456474
// Vista or earlier, use older API that is limited to 64 processors.
457475
ULONGLONG mask;
458-
if (GetNumaNodeProcessorMask((UCHAR)numa_max, &mask)) {
459-
if (mask != 0) break; // found the maximum non-empty node
476+
if (pGetNumaNodeProcessorMask != NULL) {
477+
if ((*pGetNumaNodeProcessorMask)((UCHAR)numa_max, &mask)) {
478+
if (mask != 0) break; // found the maximum non-empty node
479+
}
460480
};
461481
}
462482
// max node was invalid or had no processor assigned, try again
@@ -546,17 +566,21 @@ void _mi_prim_out_stderr( const char* msg )
546566
if (!_mi_preloading()) {
547567
// _cputs(msg); // _cputs cannot be used as it aborts when failing to lock the console
548568
static HANDLE hcon = INVALID_HANDLE_VALUE;
549-
static bool hconIsConsole;
569+
static bool hconIsConsole = false;
550570
if (hcon == INVALID_HANDLE_VALUE) {
551-
CONSOLE_SCREEN_BUFFER_INFO sbi;
552571
hcon = GetStdHandle(STD_ERROR_HANDLE);
572+
#ifdef MI_HAS_CONSOLE_IO
573+
CONSOLE_SCREEN_BUFFER_INFO sbi;
553574
hconIsConsole = ((hcon != INVALID_HANDLE_VALUE) && GetConsoleScreenBufferInfo(hcon, &sbi));
575+
#endif
554576
}
555577
const size_t len = _mi_strlen(msg);
556578
if (len > 0 && len < UINT32_MAX) {
557579
DWORD written = 0;
558580
if (hconIsConsole) {
581+
#ifdef MI_HAS_CONSOLE_IO
559582
WriteConsoleA(hcon, msg, (DWORD)len, &written, NULL);
583+
#endif
560584
}
561585
else if (hcon != INVALID_HANDLE_VALUE) {
562586
// use direct write if stderr was redirected

0 commit comments

Comments
 (0)