[PATCH 1/3] port.h: Make use of compiler support for 32bit atomic ops.
Grazvydas Ignotas
notasas at gmail.com
Mon May 11 19:17:35 CDT 2015
Works on gcc and clang.
1Ghz ARM Cortex-A8 can spin a loop with Enter/Leave CriticalSection pair:
before this patch: ~1M times/sec
after this patch: ~2.1M times/sec
---
include/wine/port.h | 24 ++++++++++++++++++++++--
libs/port/interlocked.c | 6 ++++++
2 files changed, 28 insertions(+), 2 deletions(-)
diff --git a/include/wine/port.h b/include/wine/port.h
index 3548a44..16127e0 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 f5e405c..e5b1bb9 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 )
{
--
1.9.1
More information about the wine-patches
mailing list