From dec4b9039c7241694f2c36970c8ebc2218c2e98e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 10 Mar 2026 13:52:58 +0000 Subject: [PATCH 1/3] Initial plan From de866cade0ddda6226ab271f2bb8c784c40de888 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 10 Mar 2026 14:00:05 +0000 Subject: [PATCH 2/3] fix: use InterlockedExchangeAdd for Windows atomic ops to return old value Replace InterlockedAdd/InterlockedIncrement/InterlockedDecrement with InterlockedExchangeAdd which returns the value before the operation, matching the behavior of __sync_fetch_and_add (GCC) and atomic_fetch_add (C11). Also fix ATOMIC_SUB macro parenthesization: -(n) instead of -n. Co-authored-by: ithewei <26049660+ithewei@users.noreply.github.com> --- base/hatomic.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/base/hatomic.h b/base/hatomic.h index b3533dbcc..0860e2c7f 100644 --- a/base/hatomic.h +++ b/base/hatomic.h @@ -52,10 +52,10 @@ static inline bool atomic_flag_test_and_set(atomic_flag* p) { return InterlockedCompareExchange(&p->_Value, 1, 0); } -#define ATOMIC_ADD InterlockedAdd -#define ATOMIC_SUB(p, n) InterlockedAdd(p, -n) -#define ATOMIC_INC InterlockedIncrement -#define ATOMIC_DEC InterlockedDecrement +#define ATOMIC_ADD InterlockedExchangeAdd +#define ATOMIC_SUB(p, n) InterlockedExchangeAdd(p, -(n)) +#define ATOMIC_INC(p) InterlockedExchangeAdd(p, 1) +#define ATOMIC_DEC(p) InterlockedExchangeAdd(p, -1) #elif __GNUC_PREREQ(4, 1) From 0f3ec917f14af4a2d6766f154121c9c92878b648 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 11 Mar 2026 04:05:37 +0000 Subject: [PATCH 3/3] fix: prefer GCC builtins over Interlocked for MinGW compatibility Reorder #ifdef checks so GCC-based compilers (including MinGW) use __sync_fetch_and_add builtins via a direct __GNUC__ version check, instead of relying on __GNUC_PREREQ which is broken on MinGW. Only pure MSVC now uses InterlockedExchangeAdd for atomic operations. This completely avoids any MinGW compatibility concerns with Windows Interlocked functions. Co-authored-by: ithewei <26049660+ithewei@users.noreply.github.com> --- base/hatomic.h | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/base/hatomic.h b/base/hatomic.h index 0860e2c7f..4885c65cf 100644 --- a/base/hatomic.h +++ b/base/hatomic.h @@ -44,30 +44,30 @@ typedef volatile size_t atomic_size_t; typedef struct atomic_flag { atomic_long _Value; } atomic_flag; -#ifdef _WIN32 +#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) #define ATOMIC_FLAG_TEST_AND_SET atomic_flag_test_and_set static inline bool atomic_flag_test_and_set(atomic_flag* p) { - // return InterlockedIncrement((LONG*)&p->_Value, 1); - return InterlockedCompareExchange(&p->_Value, 1, 0); + return !__sync_bool_compare_and_swap(&p->_Value, 0, 1); } -#define ATOMIC_ADD InterlockedExchangeAdd -#define ATOMIC_SUB(p, n) InterlockedExchangeAdd(p, -(n)) -#define ATOMIC_INC(p) InterlockedExchangeAdd(p, 1) -#define ATOMIC_DEC(p) InterlockedExchangeAdd(p, -1) +#define ATOMIC_ADD __sync_fetch_and_add +#define ATOMIC_SUB __sync_fetch_and_sub +#define ATOMIC_INC(p) ATOMIC_ADD(p, 1) +#define ATOMIC_DEC(p) ATOMIC_SUB(p, 1) -#elif __GNUC_PREREQ(4, 1) +#elif defined(_WIN32) #define ATOMIC_FLAG_TEST_AND_SET atomic_flag_test_and_set static inline bool atomic_flag_test_and_set(atomic_flag* p) { - return !__sync_bool_compare_and_swap(&p->_Value, 0, 1); + // return InterlockedIncrement((LONG*)&p->_Value, 1); + return InterlockedCompareExchange(&p->_Value, 1, 0); } -#define ATOMIC_ADD __sync_fetch_and_add -#define ATOMIC_SUB __sync_fetch_and_sub -#define ATOMIC_INC(p) ATOMIC_ADD(p, 1) -#define ATOMIC_DEC(p) ATOMIC_SUB(p, 1) +#define ATOMIC_ADD InterlockedExchangeAdd +#define ATOMIC_SUB(p, n) InterlockedExchangeAdd(p, -(n)) +#define ATOMIC_INC(p) InterlockedExchangeAdd(p, 1) +#define ATOMIC_DEC(p) InterlockedExchangeAdd(p, -1) #endif