@@ -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)
5054static PVirtualAlloc2 pVirtualAlloc2 = NULL ;
5155static 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)
5458typedef struct MI_PROCESSOR_NUMBER_S { WORD Group ; BYTE Number ; BYTE Reserved ; } MI_PROCESSOR_NUMBER ;
5559
5660typedef VOID (__stdcall * PGetCurrentProcessorNumberEx )(MI_PROCESSOR_NUMBER * ProcNumber );
5761typedef BOOL (__stdcall * PGetNumaProcessorNodeEx )(MI_PROCESSOR_NUMBER * Processor , PUSHORT NodeNumber );
5862typedef BOOL (__stdcall* PGetNumaNodeProcessorMaskEx )(USHORT Node , PGROUP_AFFINITY ProcessorMask );
5963typedef BOOL (__stdcall * PGetNumaProcessorNode )(UCHAR Processor , PUCHAR NodeNumber );
64+ typedef BOOL (__stdcall* PGetNumaNodeProcessorMask )(UCHAR Node , PULONGLONG ProcessorMask );
65+ typedef BOOL (__stdcall* PGetNumaHighestNodeNumber )(PULONG Node );
6066static PGetCurrentProcessorNumberEx pGetCurrentProcessorNumberEx = NULL ;
6167static PGetNumaProcessorNodeEx pGetNumaProcessorNodeEx = NULL ;
6268static PGetNumaNodeProcessorMaskEx pGetNumaNodeProcessorMaskEx = NULL ;
6369static 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
6678typedef 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
443459size_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