From: ivmai Date: Thu, 10 Sep 2009 15:39:42 +0000 (+0000) Subject: 2009-09-10 Ivan Maidanski X-Git-Tag: libatomic_ops-7_2alpha4~16 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=07e9ea93f8c50194757f0d73f6b60d308b9366a4;p=libatomic_ops 2009-09-10 Ivan Maidanski (ivmai122.diff) * src/atomic_ops/sysdeps/armcc/arm_v6.h (AO_compare_double_and_swap_double): Replace false/true with 0/1. * src/atomic_ops/sysdeps/gcc/arm.h (AO_compare_double_and_swap_double): Ditto. * src/atomic_ops/sysdeps/gcc/arm.h: Recognize more ARMv6+ predefined macros (6J, 6ZK, 7A, 7M, 7R). * src/atomic_ops/sysdeps/gcc/arm.h (AO_compare_double_and_swap_double): Add "cc" clobber to asm. * src/atomic_ops/sysdeps/gcc/powerpc.h (AO_HAVE_load_acquire): Correct the name (convert from the lower case). * src/atomic_ops/sysdeps/ibmc/powerpc.h (AO_HAVE_load_acquire): Ditto. * src/atomic_ops/sysdeps/ibmc/powerpc.h (AO_test_and_set, AO_compare_and_swap): Comment out unimplemented code (and the corresponding macros); add FIXME. * src/atomic_ops.c: Recognize AO_USE_WIN32_PTHREADS overriding _MSC_VER and __MINGW32__ predefined macros (useful for WinCE with pthreads-w32 library); don't include signal.h, sys/time.h, sys/select.h in this case; include windows.h instead. * src/atomic_ops.c (AO_pause): Use Sleep() in case of AO_USE_WIN32_PTHREADS (instead of select()). * src/atomic_ops.c (all_sigs, initialized): Don't define in case of AO_USE_WIN32_PTHREADS. * src/atomic_ops.c (AO_compare_and_swap_emulation, AO_compare_double_and_swap_double_emulation): Don't deal with signals in case of AO_USE_WIN32_PTHREADS. --- diff --git a/ChangeLog b/ChangeLog index 54d153d..80817de 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,32 @@ +2009-09-10 Ivan Maidanski + (ivmai122.diff) + * src/atomic_ops/sysdeps/armcc/arm_v6.h + (AO_compare_double_and_swap_double): Replace false/true with 0/1. + * src/atomic_ops/sysdeps/gcc/arm.h + (AO_compare_double_and_swap_double): Ditto. + * src/atomic_ops/sysdeps/gcc/arm.h: Recognize more ARMv6+ + predefined macros (6J, 6ZK, 7A, 7M, 7R). + * src/atomic_ops/sysdeps/gcc/arm.h + (AO_compare_double_and_swap_double): Add "cc" clobber to asm. + * src/atomic_ops/sysdeps/gcc/powerpc.h (AO_HAVE_load_acquire): + Correct the name (convert from the lower case). + * src/atomic_ops/sysdeps/ibmc/powerpc.h (AO_HAVE_load_acquire): + Ditto. + * src/atomic_ops/sysdeps/ibmc/powerpc.h (AO_test_and_set, + AO_compare_and_swap): Comment out unimplemented code (and the + corresponding macros); add FIXME. + * src/atomic_ops.c: Recognize AO_USE_WIN32_PTHREADS overriding + _MSC_VER and __MINGW32__ predefined macros (useful for WinCE with + pthreads-w32 library); don't include signal.h, sys/time.h, + sys/select.h in this case; include windows.h instead. + * src/atomic_ops.c (AO_pause): Use Sleep() in case of + AO_USE_WIN32_PTHREADS (instead of select()). + * src/atomic_ops.c (all_sigs, initialized): Don't define in case + of AO_USE_WIN32_PTHREADS. + * src/atomic_ops.c (AO_compare_and_swap_emulation, + AO_compare_double_and_swap_double_emulation): Don't deal with + signals in case of AO_USE_WIN32_PTHREADS. + 2009-09-10 Ivan Maidanski (diff110) * src/atomic_ops/sysdeps/msftc/arm.h: New file (initial support diff --git a/src/atomic_ops.c b/src/atomic_ops.c index 1307612..8f2e491 100644 --- a/src/atomic_ops.c +++ b/src/atomic_ops.c @@ -32,17 +32,24 @@ # include "config.h" #endif -#if !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(__BORLANDC__) +#if !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(__BORLANDC__) \ + || defined(AO_USE_WIN32_PTHREADS) #undef AO_REQUIRE_CAS #include -#include -#ifdef _HPUX_SOURCE -# include + +#ifdef AO_USE_WIN32_PTHREADS +# include /* for Sleep() */ #else -# include +# include +# ifdef _HPUX_SOURCE +# include +# else +# include +# endif #endif + #include "atomic_ops.h" /* Without cas emulation! */ #ifndef AO_HAVE_double_t @@ -104,12 +111,16 @@ void AO_pause(int n) AO_spin(n); else { +# ifdef AO_USE_WIN32_PTHREADS + Sleep(n > 28 ? 100 : 1 << (n - 22)); /* in millis */ +# else struct timeval tv; /* Short async-signal-safe sleep. */ tv.tv_sec = 0; tv.tv_usec = (n > 28? 100000 : (1 << (n - 12))); select(0, 0, 0, 0, &tv); +# endif } } @@ -132,9 +143,10 @@ AO_INLINE void unlock(volatile AO_TS_t *l) AO_CLEAR(l); } -static sigset_t all_sigs; - -static volatile AO_t initialized = 0; +#ifndef AO_USE_WIN32_PTHREADS + static sigset_t all_sigs; + static volatile AO_t initialized = 0; +#endif static volatile AO_TS_t init_lock = AO_TS_INITIALIZER; @@ -142,17 +154,18 @@ int AO_compare_and_swap_emulation(volatile AO_t *addr, AO_t old, AO_t new_val) { AO_TS_t *my_lock = AO_locks + AO_HASH(addr); - sigset_t old_sigs; int result; - if (!AO_load_acquire(&initialized)) +# ifndef AO_USE_WIN32_PTHREADS + sigset_t old_sigs; + if (!AO_load_acquire(&initialized)) { lock(&init_lock); if (!initialized) sigfillset(&all_sigs); unlock(&init_lock); AO_store_release(&initialized, 1); } - sigprocmask(SIG_BLOCK, &all_sigs, &old_sigs); + sigprocmask(SIG_BLOCK, &all_sigs, &old_sigs); /* Neither sigprocmask nor pthread_sigmask is 100% */ /* guaranteed to work here. Sigprocmask is not */ /* guaranteed be thread safe, and pthread_sigmask */ @@ -160,6 +173,7 @@ int AO_compare_and_swap_emulation(volatile AO_t *addr, AO_t old, /* sigprocmask may block some pthreads-internal */ /* signals. So long as we do that for short periods, */ /* we should be OK. */ +# endif lock(my_lock); if (*addr == old) { @@ -169,7 +183,9 @@ int AO_compare_and_swap_emulation(volatile AO_t *addr, AO_t old, else result = 0; unlock(my_lock); - sigprocmask(SIG_SETMASK, &old_sigs, NULL); +# ifndef AO_USE_WIN32_PTHREADS + sigprocmask(SIG_SETMASK, &old_sigs, NULL); +# endif return result; } @@ -178,17 +194,18 @@ int AO_compare_double_and_swap_double_emulation(volatile AO_double_t *addr, AO_t new_val1, AO_t new_val2) { AO_TS_t *my_lock = AO_locks + AO_HASH(addr); - sigset_t old_sigs; int result; - if (!AO_load_acquire(&initialized)) +# ifndef AO_USE_WIN32_PTHREADS + sigset_t old_sigs; + if (!AO_load_acquire(&initialized)) { lock(&init_lock); if (!initialized) sigfillset(&all_sigs); unlock(&init_lock); AO_store_release(&initialized, 1); } - sigprocmask(SIG_BLOCK, &all_sigs, &old_sigs); + sigprocmask(SIG_BLOCK, &all_sigs, &old_sigs); /* Neither sigprocmask nor pthread_sigmask is 100% */ /* guaranteed to work here. Sigprocmask is not */ /* guaranteed be thread safe, and pthread_sigmask */ @@ -196,6 +213,7 @@ int AO_compare_double_and_swap_double_emulation(volatile AO_double_t *addr, /* sigprocmask may block some pthreads-internal */ /* signals. So long as we do that for short periods, */ /* we should be OK. */ +# endif lock(my_lock); if (addr -> AO_val1 == old_val1 && addr -> AO_val2 == old_val2) { @@ -206,7 +224,9 @@ int AO_compare_double_and_swap_double_emulation(volatile AO_double_t *addr, else result = 0; unlock(my_lock); - sigprocmask(SIG_SETMASK, &old_sigs, NULL); +# ifndef AO_USE_WIN32_PTHREADS + sigprocmask(SIG_SETMASK, &old_sigs, NULL); +# endif return result; } diff --git a/src/atomic_ops/sysdeps/armcc/arm_v6.h b/src/atomic_ops/sysdeps/armcc/arm_v6.h index 86376eb..199ead8 100644 --- a/src/atomic_ops/sysdeps/armcc/arm_v6.h +++ b/src/atomic_ops/sysdeps/armcc/arm_v6.h @@ -222,9 +222,9 @@ AO_compare_double_and_swap_double(volatile AO_double_t *addr, while(1) { tmp = load_ex(addr); - if(tmp != old_val) return false; + if(tmp != old_val) return 0; result = store_ex(new_val1, new_val2, addr); - if(!result) return true; + if(!result) return 1; } } diff --git a/src/atomic_ops/sysdeps/gcc/arm.h b/src/atomic_ops/sysdeps/gcc/arm.h index 8a9826b..e961369 100644 --- a/src/atomic_ops/sysdeps/gcc/arm.h +++ b/src/atomic_ops/sysdeps/gcc/arm.h @@ -33,7 +33,10 @@ /* NEC LE-IT: gcc has no way to easily check the arm architecture * but defines only one of __ARM_ARCH_x__ to be true */ -#if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_7__) +#if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \ + || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6ZK__) \ + || defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \ + || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7R__) #include "../standard_ao_double_t.h" @@ -237,14 +240,14 @@ AO_compare_double_and_swap_double(volatile AO_double_t *addr, " ldrexd %0, [%1]\n" /* get original to r1&r2*/ : "=&r"(tmp) : "r"(addr) - : ); - if(tmp != old_val) return false; + : "cc"); + if(tmp != old_val) return 0; __asm__ __volatile__( " strexd %0, %2, [%3]\n" /* store new one if matched */ : "=&r"(result),"+m"(*addr) : "r"(new_val), "r"(addr) - : ); - if(!result) return true; + : "cc"); + if(!result) return 1; } } diff --git a/src/atomic_ops/sysdeps/gcc/powerpc.h b/src/atomic_ops/sysdeps/gcc/powerpc.h index 49ab63c..38cd4fe 100644 --- a/src/atomic_ops/sysdeps/gcc/powerpc.h +++ b/src/atomic_ops/sysdeps/gcc/powerpc.h @@ -162,7 +162,7 @@ AO_test_and_set(volatile AO_TS_t *addr) { #endif -#define AO_have_test_and_set +#define AO_HAVE_test_and_set AO_INLINE AO_TS_VAL_t AO_test_and_set_acquire(volatile AO_TS_t *addr) { diff --git a/src/atomic_ops/sysdeps/ibmc/powerpc.h b/src/atomic_ops/sysdeps/ibmc/powerpc.h index 4a1badb..6b858e5 100644 --- a/src/atomic_ops/sysdeps/ibmc/powerpc.h +++ b/src/atomic_ops/sysdeps/ibmc/powerpc.h @@ -52,12 +52,12 @@ AO_store_release(volatile AO_t *addr, AO_t value) /* This is similar to the code in the garbage collector. Deleting */ /* this and having it synthesized from compare_and_swap would probably */ /* only cost us a load immediate instruction. */ -AO_INLINE AO_TS_VAL_t +/*AO_INLINE AO_TS_VAL_t AO_test_and_set(volatile AO_TS_t *addr) { -# error Implement me +# error FIXME Implement me } -#define AO_have_test_and_set +#define AO_HAVE_test_and_set*/ AO_INLINE AO_TS_VAL_t AO_test_and_set_acquire(volatile AO_TS_t *addr) { @@ -87,12 +87,12 @@ AO_test_and_set_full(volatile AO_TS_t *addr) { #define AO_HAVE_test_and_set_full -AO_INLINE AO_t +/*AO_INLINE AO_t AO_compare_and_swap(volatile AO_t *addr, AO_t old, AO_t new_val) { -# error Implement me +# error FIXME Implement me } -#define AO_HAVE_compare_and_swap +#define AO_HAVE_compare_and_swap*/ AO_INLINE AO_t AO_compare_and_swap_acquire(volatile AO_t *addr, AO_t old, AO_t new_val) {