Skip to content

Commit

Permalink
Win32: Added support NUMA configuration with multiple count CPU sockets
Browse files Browse the repository at this point in the history
  • Loading branch information
GermanAizek committed Apr 5, 2024
1 parent fd655dc commit 3df26f8
Showing 1 changed file with 66 additions and 5 deletions.
71 changes: 66 additions & 5 deletions thread-utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,67 @@
# endif
#endif

#ifdef GIT_WINDOWS_NATIVE
/// defines the GetLogicalProcessorInformationEx function
typedef BOOL (*WINAPI glpie_t)(
LOGICAL_PROCESSOR_RELATIONSHIP,
PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX,
PDWORD);

// Classic way to get number of cores in windows.
static size_t get_windows_compatible_n_cores() {

Check failure on line 29 in thread-utils.c

View workflow job for this annotation

GitHub Actions / win build

thread-utils.c:29:15: function declaration isn't a prototype [-Werror=strict-prototypes]

Check failure on line 29 in thread-utils.c

View workflow job for this annotation

GitHub Actions / win build

thread-utils.c:29:15: old-style function definition [-Werror=old-style-definition]
SYSTEM_INFO info;
GetSystemInfo(&info);
if ((int)info.dwNumberOfProcessors > 0)
return (int)info.dwNumberOfProcessors;
}

Check failure on line 34 in thread-utils.c

View workflow job for this annotation

GitHub Actions / win build

thread-utils.c:34:1: control reaches end of non-void function [-Werror=return-type]

/*
* Windows NUMA support is particular
* https://learn.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getlogicalprocessorinformationex#remarks
*
* New api here:
* https://learn.microsoft.com/en-us/windows/win32/procthread/numa-support
*/
static size_t get_windows_numa_n_cores() {

Check failure on line 43 in thread-utils.c

View workflow job for this annotation

GitHub Actions / win build

thread-utils.c:43:15: function declaration isn't a prototype [-Werror=strict-prototypes]

Check failure on line 43 in thread-utils.c

View workflow job for this annotation

GitHub Actions / win build

thread-utils.c:43:15: old-style function definition [-Werror=old-style-definition]
ut8 *buffer = NULL;

Check failure on line 44 in thread-utils.c

View workflow job for this annotation

GitHub Actions / win build

thread-utils.c:44:9: unknown type name 'ut8'
size_t n_cores = 0;
DWORD length = 0;
HMODULE kernel32 = GetModuleHandleW(L"kernel32.dll");

glpie_t GetLogicalProcessorInformationEx = (glpie_t)GetProcAddress(kernel32, "GetLogicalProcessorInformationEx");

Check failure on line 49 in thread-utils.c

View workflow job for this annotation

GitHub Actions / win build

thread-utils.c:49:52: cast between incompatible function types from 'FARPROC' {aka 'long long int (*)()'} to 'BOOL (*)(LOGICAL_PROCESSOR_RELATIONSHIP, struct _SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *, DWORD *)' {aka 'int (*)(LOGICAL_PROCESSOR_RELATIONSHIP, struct _SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *, long unsigned int *)'} [-Werror=cast-function-type]
if (!GetLogicalProcessorInformationEx) {
return 0;
}

GetLogicalProcessorInformationEx(RelationAll, NULL, &length);
if (length < 1 || GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
return 0;
}

buffer = malloc(length);
if (!buffer || !GetLogicalProcessorInformationEx(RelationAll, (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX)buffer, &length)) {
free(buffer);
return 0;
}

for (DWORD offset = 0; offset < length;) {
PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX info = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX)(buffer + offset);
offset += info->Size;
if (info->Relationship != RelationProcessorCore) {
continue;
}
for (WORD group = 0; group < info->Processor.GroupCount; ++group) {
for (KAFFINITY mask = info->Processor.GroupMask[group].Mask; mask != 0; mask >>= 1) {
n_cores += mask & 1;
}
}
}
free(buffer);
return n_cores;
}
#endif

int online_cpus(void)
{
#ifdef NO_PTHREADS
Expand All @@ -28,11 +89,11 @@ int online_cpus(void)
#endif

#ifdef GIT_WINDOWS_NATIVE
SYSTEM_INFO info;
GetSystemInfo(&info);

if ((int)info.dwNumberOfProcessors > 0)
return (int)info.dwNumberOfProcessors;
size_t n_cores = get_windows_numa_n_cores();
if (n_cores > 0) {
return n_cores;
}
return get_windows_compatible_n_cores();
#elif defined(hpux) || defined(__hpux) || defined(_hpux)
struct pst_dynamic psd;

Expand Down

0 comments on commit 3df26f8

Please sign in to comment.