diff --git a/include/wine/port.h b/include/wine/port.h index 3548a44ac4f..16127e0b792 100644 --- a/include/wine/port.h +++ b/include/wine/port.h @@ -435,12 +435,32 @@ static inline unsigned char interlocked_cmpxchg128( __int64 *dest, __int64 xchg_ #else /* __GNUC__ */ +#ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 +static inline int interlocked_cmpxchg( int *dest, int xchg, int compare ) +{ + return __sync_val_compare_and_swap( dest, compare, xchg ); +} + +static inline int interlocked_xchg_add( int *dest, int incr ) +{ + return __sync_fetch_and_add( dest, incr ); +} + +static inline int interlocked_xchg( int *dest, int val ) +{ + int ret; + do ret = *dest; while (!__sync_bool_compare_and_swap( dest, ret, val )); + return ret; +} +#else extern int interlocked_cmpxchg( int *dest, int xchg, int compare ); +extern int interlocked_xchg_add( int *dest, int incr ); +extern int interlocked_xchg( int *dest, int val ); +#endif + extern void *interlocked_cmpxchg_ptr( void **dest, void *xchg, void *compare ); extern __int64 interlocked_cmpxchg64( __int64 *dest, __int64 xchg, __int64 compare ); -extern int interlocked_xchg( int *dest, int val ); extern void *interlocked_xchg_ptr( void **dest, void *val ); -extern int interlocked_xchg_add( int *dest, int incr ); #if defined(__x86_64__) || defined(__aarch64__) || defined(_WIN64) extern unsigned char interlocked_cmpxchg128( __int64 *dest, __int64 xchg_high, __int64 xchg_low, __int64 *compare ); diff --git a/libs/port/interlocked.c b/libs/port/interlocked.c index f5e405c961a..e5b1bb9d81e 100644 --- a/libs/port/interlocked.c +++ b/libs/port/interlocked.c @@ -274,6 +274,7 @@ void* interlocked_xchg_ptr( void** dest, void* val ) static pthread_mutex_t interlocked_mutex = PTHREAD_MUTEX_INITIALIZER; +#ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 int interlocked_cmpxchg( int *dest, int xchg, int compare ) { pthread_mutex_lock( &interlocked_mutex ); @@ -286,6 +287,7 @@ int interlocked_cmpxchg( int *dest, int xchg, int compare ) pthread_mutex_unlock( &interlocked_mutex ); return compare; } +#endif void *interlocked_cmpxchg_ptr( void **dest, void *xchg, void *compare ) { @@ -313,6 +315,7 @@ __int64 interlocked_cmpxchg64( __int64 *dest, __int64 xchg, __int64 compare ) return compare; } +#ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 int interlocked_xchg( int *dest, int val ) { int retv; @@ -322,6 +325,7 @@ int interlocked_xchg( int *dest, int val ) pthread_mutex_unlock( &interlocked_mutex ); return retv; } +#endif void *interlocked_xchg_ptr( void **dest, void *val ) { @@ -333,6 +337,7 @@ void *interlocked_xchg_ptr( void **dest, void *val ) return retv; } +#ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 int interlocked_xchg_add( int *dest, int incr ) { int retv; @@ -342,6 +347,7 @@ int interlocked_xchg_add( int *dest, int incr ) pthread_mutex_unlock( &interlocked_mutex ); return retv; } +#endif unsigned char interlocked_cmpxchg128( __int64 *dest, __int64 xchg_high, __int64 xchg_low, __int64 *compare ) {