From 3b2e0093f725db8be9bcfee55d7fbfecc08bee5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20A=C3=9Fhauer?= Date: Sat, 21 Feb 2026 10:12:19 +0100 Subject: [PATCH 1/2] unify and bump _WIN32_WINNT definition to Windows 8.1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Git for Windows doesn't support anything prior to Windows 8.1 since 2.47.0 and Git followed along with commits like ce6ccba (mingw: drop Windows 7-specific work-around, 2025-08-04). There is no need to pretend to the compiler that we still support Windows Vista, just to lock us out of easy access to newer APIs. There is also no need to have conflicting and unused definitions claiming we support some versions of Windows XP or even Windows NT 4.0. Bump all definitions of _WIN32_WINNT to a realistic value of Windows 8.1. This will also simplify code for a followup commit that will improve cpu core detection on multi-socket systems. Signed-off-by: Matthias Aßhauer --- compat/mingw.c | 2 +- compat/nedmalloc/malloc.c.h | 2 +- compat/poll/poll.c | 4 ++-- compat/posix.h | 2 +- compat/win32/flush.c | 2 ++ 5 files changed, 7 insertions(+), 5 deletions(-) diff --git a/compat/mingw.c b/compat/mingw.c index 5a9807e7a42b41..656d29307343d7 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -2938,7 +2938,7 @@ int mingw_rename(const char *pold, const char *pnew) if (supports_file_rename_info_ex) { /* * Our minimum required Windows version is still set to Windows - * Vista. We thus have to declare required infrastructure for + * 8.1. We thus have to declare required infrastructure for * FileRenameInfoEx ourselves until we bump _WIN32_WINNT to * 0x0A00. Furthermore, we have to handle cases where the * FileRenameInfoEx call isn't supported yet. diff --git a/compat/nedmalloc/malloc.c.h b/compat/nedmalloc/malloc.c.h index 814845d4b33fc8..e0c567586c878c 100644 --- a/compat/nedmalloc/malloc.c.h +++ b/compat/nedmalloc/malloc.c.h @@ -500,7 +500,7 @@ MAX_RELEASE_CHECK_RATE default: 4095 unless not HAVE_MMAP #ifdef WIN32 #define WIN32_LEAN_AND_MEAN #ifndef _WIN32_WINNT -#define _WIN32_WINNT 0x403 +#define _WIN32_WINNT 0x603 #endif #include #define HAVE_MMAP 1 diff --git a/compat/poll/poll.c b/compat/poll/poll.c index a2becd16cd0bd0..ea362b4a8e2340 100644 --- a/compat/poll/poll.c +++ b/compat/poll/poll.c @@ -20,7 +20,7 @@ #define DISABLE_SIGN_COMPARE_WARNINGS -/* To bump the minimum Windows version to Windows Vista */ +/* To bump the minimum Windows version to Windows 8.1 */ #include "git-compat-util.h" /* Tell gcc not to warn about the (nfd < 0) tests, below. */ @@ -41,7 +41,7 @@ #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ # define WIN32_NATIVE # if defined (_MSC_VER) && !defined(_WIN32_WINNT) -# define _WIN32_WINNT 0x0502 +# define _WIN32_WINNT 0x0603 # endif # include # include diff --git a/compat/posix.h b/compat/posix.h index 6c730aa83d572d..664a9ebe331b4c 100644 --- a/compat/posix.h +++ b/compat/posix.h @@ -78,7 +78,7 @@ #if defined(WIN32) && !defined(__CYGWIN__) /* Both MinGW and MSVC */ # if !defined(_WIN32_WINNT) -# define _WIN32_WINNT 0x0600 +# define _WIN32_WINNT 0x0603 # endif #define WIN32_LEAN_AND_MEAN /* stops windows.h including winsock.h */ #include diff --git a/compat/win32/flush.c b/compat/win32/flush.c index 291f90ea9406ba..7244ff69ac08b7 100644 --- a/compat/win32/flush.c +++ b/compat/win32/flush.c @@ -6,7 +6,9 @@ int win32_fsync_no_flush(int fd) { IO_STATUS_BLOCK io_status; +#ifndef FLUSH_FLAGS_FILE_DATA_ONLY #define FLUSH_FLAGS_FILE_DATA_ONLY 1 +#endif DECLARE_PROC_ADDR(ntdll.dll, NTSTATUS, NTAPI, NtFlushBuffersFileEx, HANDLE FileHandle, ULONG Flags, PVOID Parameters, ULONG ParameterSize, From 5ce2b45bb3498767402f16cb4975399da9527690 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20A=C3=9Fhauer?= Date: Sat, 21 Feb 2026 12:11:02 +0100 Subject: [PATCH 2/2] win32: thread-utils: handle multi-socket systems MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While the currently used way to detect the number of CPU cores on Windows is nice and straight-forward, GetSystemInfo() only gives us access to the number of processors within the current group. [1] While that is usually fine for systems with a single physical CPU, separate physical sockets are typically separate groups. Switch to using GetLogicalProcessorInformationEx() to handle multi-socket systems better. [1] https://learn.microsoft.com/en-us/windows/win32/api/sysinfoapi/ns-sysinfoapi-system_info#members This fixes https://github.com/git-for-windows/git/issues/4766 Co-Authored-by: Herman Semenov Signed-off-by: Matthias Aßhauer --- thread-utils.c | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/thread-utils.c b/thread-utils.c index 374890e6b05b69..00e7e9192b3e0b 100644 --- a/thread-utils.c +++ b/thread-utils.c @@ -28,11 +28,28 @@ int online_cpus(void) #endif #ifdef GIT_WINDOWS_NATIVE - SYSTEM_INFO info; - GetSystemInfo(&info); - - if ((int)info.dwNumberOfProcessors > 0) - return (int)info.dwNumberOfProcessors; + DWORD len = 0; + if (!GetLogicalProcessorInformationEx(RelationProcessorCore, NULL, &len) && GetLastError() == ERROR_INSUFFICIENT_BUFFER) { + uint8_t *buf = malloc(len); + if (buf) { + if (GetLogicalProcessorInformationEx(RelationProcessorCore, (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX) buf, &len)) { + DWORD offset = 0; + int n_cores = 0; + while (offset < len) { + PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX info = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX) (buf + offset); + offset += info->Size; + /* The threads within a core always share a single group. We need to count the bits in the mask to get a thread count. */ + for (KAFFINITY mask = info->Processor.GroupMask[0].Mask; mask; mask >>= 1) + n_cores += mask &1; + } + if (n_cores) { + free(buf); + return n_cores; + } + } + free(buf); + } + } #elif defined(hpux) || defined(__hpux) || defined(_hpux) struct pst_dynamic psd;