[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