From adb45d2294c0b165970a9b7d03713c8bc768ba0a Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Sat, 2 May 2020 15:09:58 +0200 Subject: [PATCH] include: Use the gcc interlocked functions also on i386 if possible. Signed-off-by: Alexandre Julliard --- include/winbase.h | 85 ++++++++++++++++++++-------------------------- include/winternl.h | 1 + 2 files changed, 38 insertions(+), 48 deletions(-) diff --git a/include/winbase.h b/include/winbase.h index 1f36782d208..f92d864c781 100644 --- a/include/winbase.h +++ b/include/winbase.h @@ -2975,71 +2975,63 @@ static FORCEINLINE void *WINAPI InterlockedExchangePointer( void *volatile *dest #endif -#elif defined(__i386__) -# if defined(__GNUC__) && !defined(_NTSYSTEM_) && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 2))) +#elif defined(__GNUC__) static FORCEINLINE LONG WINAPI InterlockedCompareExchange( LONG volatile *dest, LONG xchg, LONG compare ) { +#ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 + return __sync_val_compare_and_swap( dest, compare, xchg ); +#else LONG ret; __asm__ __volatile__( "lock; cmpxchgl %2,(%1)" : "=a" (ret) : "r" (dest), "r" (xchg), "0" (compare) : "memory" ); return ret; +#endif } static FORCEINLINE LONG WINAPI InterlockedExchange( LONG volatile *dest, LONG val ) { LONG ret; +#if defined(__i386__) || defined(__x86_64__) __asm__ __volatile__( "lock; xchgl %0,(%1)" : "=r" (ret) :"r" (dest), "0" (val) : "memory" ); +#else + do ret = *dest; while (!__sync_bool_compare_and_swap( dest, ret, val )); +#endif return ret; } static FORCEINLINE LONG WINAPI InterlockedExchangeAdd( LONG volatile *dest, LONG incr ) { +#ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 + return __sync_fetch_and_add( dest, incr ); +#else LONG ret; __asm__ __volatile__( "lock; xaddl %0,(%1)" : "=r" (ret) : "r" (dest), "0" (incr) : "memory" ); return ret; +#endif } static FORCEINLINE LONG WINAPI InterlockedIncrement( LONG volatile *dest ) { +#ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 + return __sync_add_and_fetch( dest, 1 ); +#else return InterlockedExchangeAdd( dest, 1 ) + 1; +#endif } static FORCEINLINE LONG WINAPI InterlockedDecrement( LONG volatile *dest ) { +#ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 + return __sync_add_and_fetch( dest, -1 ); +#else return InterlockedExchangeAdd( dest, -1 ) - 1; +#endif } -# else /* __GNUC__ */ - -WINBASEAPI LONG WINAPI InterlockedCompareExchange(LONG volatile*,LONG,LONG); -WINBASEAPI LONG WINAPI InterlockedDecrement(LONG volatile*); -WINBASEAPI LONG WINAPI InterlockedExchange(LONG volatile*,LONG); -WINBASEAPI LONG WINAPI InterlockedExchangeAdd(LONG volatile*,LONG); -WINBASEAPI LONG WINAPI InterlockedIncrement(LONG volatile*); - -# endif /* __GNUC__ */ - -static FORCEINLINE PVOID WINAPI InterlockedCompareExchangePointer( PVOID volatile *dest, PVOID xchg, PVOID compare ) -{ - return (PVOID)InterlockedCompareExchange( (LONG volatile*)dest, (LONG)xchg, (LONG)compare ); -} - -static FORCEINLINE PVOID WINAPI InterlockedExchangePointer( PVOID volatile *dest, PVOID val ) -{ - return (PVOID)InterlockedExchange( (LONG volatile*)dest, (LONG)val ); -} - -WINBASEAPI LONGLONG WINAPI InterlockedCompareExchange64(LONGLONG volatile*,LONGLONG,LONGLONG); - -#elif defined(__GNUC__) - -static FORCEINLINE LONG WINAPI InterlockedCompareExchange( LONG volatile *dest, LONG xchg, LONG compare ) -{ - return __sync_val_compare_and_swap( dest, compare, xchg ); -} +#ifdef _WIN64 static FORCEINLINE PVOID WINAPI InterlockedCompareExchangePointer( PVOID volatile *dest, PVOID xchg, PVOID compare ) { @@ -3051,17 +3043,6 @@ static FORCEINLINE LONGLONG WINAPI InterlockedCompareExchange64( LONGLONG volati return __sync_val_compare_and_swap( dest, compare, xchg ); } -static FORCEINLINE LONG WINAPI InterlockedExchange( LONG volatile *dest, LONG val ) -{ - LONG ret; -#ifdef __x86_64__ - __asm__ __volatile__( "lock; xchgl %0,(%1)" : "=r" (ret) :"r" (dest), "0" (val) : "memory" ); -#else - do ret = *dest; while (!__sync_bool_compare_and_swap( dest, ret, val )); -#endif - return ret; -} - static FORCEINLINE PVOID WINAPI InterlockedExchangePointer( PVOID volatile *dest, PVOID val ) { PVOID ret; @@ -3073,22 +3054,30 @@ static FORCEINLINE PVOID WINAPI InterlockedExchangePointer( PVOID volatile *dest return ret; } -static FORCEINLINE LONG WINAPI InterlockedExchangeAdd( LONG volatile *dest, LONG incr ) +#else + +static FORCEINLINE PVOID WINAPI InterlockedCompareExchangePointer( PVOID volatile *dest, PVOID xchg, PVOID compare ) { - return __sync_fetch_and_add( dest, incr ); + return (PVOID)InterlockedCompareExchange( (LONG volatile*)dest, (LONG)xchg, (LONG)compare ); } -static FORCEINLINE LONG WINAPI InterlockedIncrement( LONG volatile *dest ) +static FORCEINLINE PVOID WINAPI InterlockedExchangePointer( PVOID volatile *dest, PVOID val ) { - return __sync_add_and_fetch( dest, 1 ); + return (PVOID)InterlockedExchange( (LONG volatile*)dest, (LONG)val ); } -static FORCEINLINE LONG WINAPI InterlockedDecrement( LONG volatile *dest ) +#ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 +static FORCEINLINE LONGLONG WINAPI InterlockedCompareExchange64( LONGLONG volatile *dest, LONGLONG xchg, LONGLONG compare ) { - return __sync_add_and_fetch( dest, -1 ); + return __sync_val_compare_and_swap( dest, compare, xchg ); } +#else +WINBASEAPI LONGLONG WINAPI InterlockedCompareExchange64(LONGLONG volatile*,LONGLONG,LONGLONG); +#endif -#endif /* __i386__ */ +#endif + +#endif /* __GNUC__ */ #ifdef __WINESRC__ diff --git a/include/winternl.h b/include/winternl.h index 87d0bde2955..fec07412049 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -3078,6 +3078,7 @@ NTSYSAPI UINT WINAPI RtlEnlargedUnsignedDivide(ULONGLONG,UINT,UINT *); NTSYSAPI LONGLONG WINAPI RtlExtendedMagicDivide(LONGLONG,LONGLONG,INT); NTSYSAPI LONGLONG WINAPI RtlExtendedIntegerMultiply(LONGLONG,INT); NTSYSAPI LONGLONG WINAPI RtlExtendedLargeIntegerDivide(LONGLONG,INT,INT *); +NTSYSAPI LONGLONG WINAPI RtlInterlockedCompareExchange64(LONGLONG*,LONGLONG,LONGLONG); NTSYSAPI LONGLONG WINAPI RtlLargeIntegerAdd(LONGLONG,LONGLONG); NTSYSAPI LONGLONG WINAPI RtlLargeIntegerArithmeticShift(LONGLONG,INT); NTSYSAPI ULONGLONG WINAPI RtlLargeIntegerDivide( ULONGLONG,ULONGLONG,ULONGLONG *);