Signed-off-by: Zebediah Figura z.figura12@gmail.com --- v2: avoid 16-bit __atomic_compare_exchange_n()
include/winnt.h | 53 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+)
diff --git a/include/winnt.h b/include/winnt.h index 1bb29836a3d..f2cfdcb3aa5 100644 --- a/include/winnt.h +++ b/include/winnt.h @@ -6978,6 +6978,59 @@ static FORCEINLINE void * WINAPI InterlockedExchangePointer( void *volatile *des
#endif
+#elif defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7))) + +static FORCEINLINE LONG WINAPI InterlockedCompareExchange( LONG volatile *dest, LONG xchg, LONG compare ) +{ + __atomic_compare_exchange_n( dest, &compare, xchg, TRUE, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ); + return compare; +} + +static FORCEINLINE PVOID WINAPI InterlockedCompareExchangePointer( PVOID volatile *dest, PVOID xchg, PVOID compare ) +{ + __atomic_compare_exchange_n( dest, &compare, xchg, TRUE, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ); + return compare; +} + +static FORCEINLINE LONGLONG WINAPI InterlockedCompareExchange64( LONGLONG volatile *dest, LONGLONG xchg, LONGLONG compare ) +{ + __atomic_compare_exchange_n( dest, &compare, xchg, TRUE, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ); + return compare; +} + +#ifdef _WIN64 +static FORCEINLINE unsigned char WINAPI InterlockedCompareExchange128( volatile __int64 *dest, __int64 xchg_high, __int64 xchg_low, __int64 *compare ) +{ + /* __atomic_compare_exchange_n() generates a call to libatomic on gcc */ + return __sync_bool_compare_and_swap( (__int128 *)dest, *(__int128 *)compare, ((__int128)xchg_high << 64) | xchg_low ); +} +#endif + +static FORCEINLINE LONG WINAPI InterlockedExchange( LONG volatile *dest, LONG val ) +{ + return __atomic_exchange_n( dest, val, __ATOMIC_SEQ_CST ); +} + +static FORCEINLINE LONG WINAPI InterlockedExchangeAdd( LONG volatile *dest, LONG incr ) +{ + return __atomic_fetch_add( dest, incr, __ATOMIC_SEQ_CST ); +} + +static FORCEINLINE LONG WINAPI InterlockedIncrement( LONG volatile *dest ) +{ + return __atomic_add_fetch( dest, 1, __ATOMIC_SEQ_CST ); +} + +static FORCEINLINE LONG WINAPI InterlockedDecrement( LONG volatile *dest ) +{ + return __atomic_add_fetch( dest, -1, __ATOMIC_SEQ_CST ); +} + +static FORCEINLINE PVOID WINAPI InterlockedExchangePointer( PVOID volatile *dest, PVOID val ) +{ + return __atomic_exchange_n( dest, val, __ATOMIC_SEQ_CST ); +} + #elif defined(__GNUC__)
static FORCEINLINE LONG WINAPI InterlockedCompareExchange( LONG volatile *dest, LONG xchg, LONG compare )