Conversation
…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>
There was a problem hiding this comment.
Pull request overview
Aligns Windows atomic operation return values with Linux (__sync_fetch_and_*) and C11 (atomic_fetch_*) semantics by making ATOMIC_* return the pre-operation value, fixing cross-platform correctness for patterns like reference counting.
Changes:
- Switch Windows
ATOMIC_ADD/ATOMIC_SUBtoInterlockedExchangeAdd(returns original value). - Implement Windows
ATOMIC_INC/ATOMIC_DECviaInterlockedExchangeAddwith+1/-1(returns original value). - Fix
ATOMIC_SUBnegation parenthesization (-(n)).
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
base/hatomic.h
Outdated
| #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) |
There was a problem hiding this comment.
This change intentionally alters Windows return semantics for ATOMIC_ADD/SUB/INC/DEC to match fetch_* (returning the pre-operation value). There’s a unit test for hatomic, but it only prints values and doesn’t assert these semantics; please add an explicit regression test that verifies both the returned value and the stored counter value for inc/dec/add/sub (especially on Windows) so this doesn’t regress again.
|
@copilot InterlockedExchangeAdd 在mingw平台上有吗,担心影响mingw编译 |
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>
|
ATOMIC_INC/ATOMIC_DEC/ATOMIC_ADD/ATOMIC_SUBreturn the new value on Windows (InterlockedIncrement/InterlockedDecrement/InterlockedAdd) but the old value on Linux (__sync_fetch_and_add) and C11 (atomic_fetch_add). This breaks cross-platform code like reference counting:#ifdefchecks so GCC-based compilers (including MinGW) use__sync_fetch_and_addbuiltins via a direct__GNUC__version check, instead of the broken__GNUC_PREREQmacro (which always evaluates to 0 on MinGW since it lacks glibc's<features.h>)InterlockedAdd/InterlockedIncrement/InterlockedDecrementwithInterlockedExchangeAdd, which returns the original valueATOMIC_SUBmacro parenthesization:-(n)instead of-nOriginal prompt
💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.