+2009-09-10 Ivan Maidanski <ivmai@mail.ru>
+ (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 <ivmai@mail.ru>
(diff110)
* src/atomic_ops/sysdeps/msftc/arm.h: New file (initial support
# 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 <pthread.h>
-#include <signal.h>
-#ifdef _HPUX_SOURCE
-# include <sys/time.h>
+
+#ifdef AO_USE_WIN32_PTHREADS
+# include <windows.h> /* for Sleep() */
#else
-# include <sys/select.h>
+# include <signal.h>
+# ifdef _HPUX_SOURCE
+# include <sys/time.h>
+# else
+# include <sys/select.h>
+# endif
#endif
+
#include "atomic_ops.h" /* Without cas emulation! */
#ifndef AO_HAVE_double_t
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
}
}
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;
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 */
/* 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)
{
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;
}
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 */
/* 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)
{
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;
}
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;
}
}
/* 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"
" 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;
}
}
#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) {
/* 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) {
#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) {