Module: wine Branch: master Commit: c741ad7dde3210843bb0d9eb07145e5f705bf355 URL: http://source.winehq.org/git/wine.git/?a=commit;h=c741ad7dde3210843bb0d9eb07...
Author: Colin Fowler elethiomel@gmail.com Date: Fri Sep 25 16:53:17 2009 +0100
libport: Add generic interlocked instruction support fallback.
---
libs/port/interlocked.c | 147 ++++++++++++++++++++++++----------------------- 1 files changed, 75 insertions(+), 72 deletions(-)
diff --git a/libs/port/interlocked.c b/libs/port/interlocked.c index 51794d3..b2d4b52 100644 --- a/libs/port/interlocked.c +++ b/libs/port/interlocked.c @@ -268,77 +268,6 @@ void* interlocked_xchg_ptr( void** dest, void* val ) return ret; }
-#elif defined(__sparc__) && defined(__sun__) - -/* - * As the earlier Sparc processors lack necessary atomic instructions, - * I'm simply falling back to the library-provided _lwp_mutex routines - * to ensure mutual exclusion in a way appropriate for the current - * architecture. - * - * FIXME: If we have the compare-and-swap instruction (Sparc v9 and above) - * we could use this to speed up the Interlocked operations ... - */ -#include <synch.h> -static lwp_mutex_t interlocked_mutex = DEFAULTMUTEX; - -int interlocked_cmpxchg( int *dest, int xchg, int compare ) -{ - _lwp_mutex_lock( &interlocked_mutex ); - if (*dest == compare) *dest = xchg; - else compare = *dest; - _lwp_mutex_unlock( &interlocked_mutex ); - return compare; -} - -void *interlocked_cmpxchg_ptr( void **dest, void *xchg, void *compare ) -{ - _lwp_mutex_lock( &interlocked_mutex ); - if (*dest == compare) *dest = xchg; - else compare = *dest; - _lwp_mutex_unlock( &interlocked_mutex ); - return compare; -} - -__int64 interlocked_cmpxchg64( __int64 *dest, __int64 xchg, __int64 compare ) -{ - _lwp_mutex_lock( &interlocked_mutex ); - if (*dest == compare) *dest = xchg; - else compare = *dest; - _lwp_mutex_unlock( &interlocked_mutex ); - return compare; -} - -int interlocked_xchg( int *dest, int val ) -{ - int retv; - _lwp_mutex_lock( &interlocked_mutex ); - retv = *dest; - *dest = val; - _lwp_mutex_unlock( &interlocked_mutex ); - return retv; -} - -void *interlocked_xchg_ptr( void **dest, void *val ) -{ - void *retv; - _lwp_mutex_lock( &interlocked_mutex ); - retv = *dest; - *dest = val; - _lwp_mutex_unlock( &interlocked_mutex ); - return retv; -} - -int interlocked_xchg_add( int *dest, int incr ) -{ - int retv; - _lwp_mutex_lock( &interlocked_mutex ); - retv = *dest; - *dest += incr; - _lwp_mutex_unlock( &interlocked_mutex ); - return retv; -} - #elif defined(__ALPHA__) && defined(__GNUC__)
__ASM_GLOBAL_FUNC(interlocked_cmpxchg, @@ -395,6 +324,80 @@ __ASM_GLOBAL_FUNC(interlocked_xchg_add, "beq $1,L0xchg_add\n\t" "mb")
+ #else -# error You must implement the interlocked* functions for your CPU + +#include <pthread.h> + +static pthread_mutex_t interlocked_mutex = PTHREAD_MUTEX_INITIALIZER; + +int interlocked_cmpxchg( int *dest, int xchg, int compare ) +{ + pthread_mutex_lock( &interlocked_mutex ); + + if (*dest == compare) + *dest = xchg; + else + compare = *dest; + + pthread_mutex_unlock( &interlocked_mutex ); + return compare; +} + +void *interlocked_cmpxchg_ptr( void **dest, void *xchg, void *compare ) +{ + pthread_mutex_lock( &interlocked_mutex ); + + if (*dest == compare) + *dest = xchg; + else + compare = *dest; + + pthread_mutex_unlock( &interlocked_mutex ); + return compare; +} + +__int64 interlocked_cmpxchg64( __int64 *dest, __int64 xchg, __int64 compare ) +{ + pthread_mutex_lock( &interlocked_mutex ); + + if (*dest == compare) + *dest = xchg; + else + compare = *dest; + + pthread_mutex_unlock( &interlocked_mutex ); + return compare; +} + +int interlocked_xchg( int *dest, int val ) +{ + int retv; + pthread_mutex_lock( &interlocked_mutex ); + retv = *dest; + *dest = val; + pthread_mutex_unlock( &interlocked_mutex ); + return retv; +} + +void *interlocked_xchg_ptr( void **dest, void *val ) +{ + void *retv; + pthread_mutex_lock( &interlocked_mutex ); + retv = *dest; + *dest = val; + pthread_mutex_unlock( &interlocked_mutex ); + return retv; +} + +int interlocked_xchg_add( int *dest, int incr ) +{ + int retv; + pthread_mutex_lock( &interlocked_mutex ); + retv = *dest; + *dest += incr; + pthread_mutex_unlock( &interlocked_mutex ); + return retv; +} + #endif