* src/atomic_ops.c (lock, block_all_signals): Use AO_EXPECT_FALSE.
* src/atomic_ops.h (AO_EXPECT_FALSE): New macro.
* src/atomic_ops/generalize-small.template
(AO_XSIZE_fetch_and_add_full, AO_XSIZE_fetch_and_add_acquire,
AO_XSIZE_fetch_and_add_release): Use AO_EXPECT_FALSE for CAS failure
check.
* src/atomic_ops/generalize.h (AO_fetch_and_add_full,
AO_fetch_and_add_acquire, AO_fetch_and_add_release, AO_fetch_and_add,
AO_and_full, AO_or_full, AO_xor_full): Likewise.
* src/atomic_ops/sysdeps/gcc/arm.h
(AO_compare_double_and_swap_double): Likewise.
* src/atomic_ops_stack.c (AO_stack_push_explicit_aux_release,
AO_stack_pop_explicit_aux_acquire, AO_stack_push_release,
AO_stack_pop_acquire): Likewise.
* src/atomic_ops/generalize-small.h: Regenerate.
AO_INLINE void lock(volatile AO_TS_t *l)
{
- if (AO_test_and_set_acquire(l) == AO_TS_SET)
+ if (AO_EXPECT_FALSE(AO_test_and_set_acquire(l) == AO_TS_SET))
lock_ool(l);
}
AO_INLINE void block_all_signals(sigset_t *old_sigs_ptr)
{
- if (!AO_load_acquire(&initialized))
+ if (AO_EXPECT_FALSE(!AO_load_acquire(&initialized)))
{
lock(&init_lock);
if (!initialized)
# define AO_INLINE static
#endif
+#if __GNUC__ >= 3 && !defined(LINT2)
+# define AO_EXPECT_FALSE(expr) __builtin_expect(expr, 0)
+ /* Equivalent to (expr) but predict that usually (expr) == 0. */
+#else
+# define AO_EXPECT_FALSE(expr) (expr)
+#endif /* !__GNUC__ */
+
#if defined(__GNUC__) && !defined(__INTEL_COMPILER)
# define AO_compiler_barrier() __asm__ __volatile__("" : : : "memory")
#elif defined(_MSC_VER) || defined(__DMC__) || defined(__BORLANDC__) \
{
old = *addr;
}
- while (!AO_char_compare_and_swap_full(addr, old, old+incr));
+ while (AO_EXPECT_FALSE(!AO_char_compare_and_swap_full(addr, old,
+ old + incr)));
return old;
}
# define AO_HAVE_char_fetch_and_add_full
{
old = *addr;
}
- while (!AO_char_compare_and_swap_acquire(addr, old, old+incr));
+ while (AO_EXPECT_FALSE(!AO_char_compare_and_swap_acquire(addr, old,
+ old + incr)));
return old;
}
# define AO_HAVE_char_fetch_and_add_acquire
{
old = *addr;
}
- while (!AO_char_compare_and_swap_release(addr, old, old+incr));
+ while (AO_EXPECT_FALSE(!AO_char_compare_and_swap_release(addr, old,
+ old + incr)));
return old;
}
# define AO_HAVE_char_fetch_and_add_release
{
old = *addr;
}
- while (!AO_short_compare_and_swap_full(addr, old, old+incr));
+ while (AO_EXPECT_FALSE(!AO_short_compare_and_swap_full(addr, old,
+ old + incr)));
return old;
}
# define AO_HAVE_short_fetch_and_add_full
{
old = *addr;
}
- while (!AO_short_compare_and_swap_acquire(addr, old, old+incr));
+ while (AO_EXPECT_FALSE(!AO_short_compare_and_swap_acquire(addr, old,
+ old + incr)));
return old;
}
# define AO_HAVE_short_fetch_and_add_acquire
{
old = *addr;
}
- while (!AO_short_compare_and_swap_release(addr, old, old+incr));
+ while (AO_EXPECT_FALSE(!AO_short_compare_and_swap_release(addr, old,
+ old + incr)));
return old;
}
# define AO_HAVE_short_fetch_and_add_release
{
old = *addr;
}
- while (!AO_int_compare_and_swap_full(addr, old, old+incr));
+ while (AO_EXPECT_FALSE(!AO_int_compare_and_swap_full(addr, old,
+ old + incr)));
return old;
}
# define AO_HAVE_int_fetch_and_add_full
{
old = *addr;
}
- while (!AO_int_compare_and_swap_acquire(addr, old, old+incr));
+ while (AO_EXPECT_FALSE(!AO_int_compare_and_swap_acquire(addr, old,
+ old + incr)));
return old;
}
# define AO_HAVE_int_fetch_and_add_acquire
{
old = *addr;
}
- while (!AO_int_compare_and_swap_release(addr, old, old+incr));
+ while (AO_EXPECT_FALSE(!AO_int_compare_and_swap_release(addr, old,
+ old + incr)));
return old;
}
# define AO_HAVE_int_fetch_and_add_release
{
old = *addr;
}
- while (!AO_XSIZE_compare_and_swap_full(addr, old, old+incr));
+ while (AO_EXPECT_FALSE(!AO_XSIZE_compare_and_swap_full(addr, old,
+ old + incr)));
return old;
}
# define AO_HAVE_XSIZE_fetch_and_add_full
{
old = *addr;
}
- while (!AO_XSIZE_compare_and_swap_acquire(addr, old, old+incr));
+ while (AO_EXPECT_FALSE(!AO_XSIZE_compare_and_swap_acquire(addr, old,
+ old + incr)));
return old;
}
# define AO_HAVE_XSIZE_fetch_and_add_acquire
{
old = *addr;
}
- while (!AO_XSIZE_compare_and_swap_release(addr, old, old+incr));
+ while (AO_EXPECT_FALSE(!AO_XSIZE_compare_and_swap_release(addr, old,
+ old + incr)));
return old;
}
# define AO_HAVE_XSIZE_fetch_and_add_release
{
old = *addr;
}
- while (!AO_compare_and_swap_full(addr, old, old+incr));
+ while (AO_EXPECT_FALSE(!AO_compare_and_swap_full(addr, old, old+incr)));
return old;
}
# define AO_HAVE_fetch_and_add_full
{
old = *addr;
}
- while (!AO_compare_and_swap_acquire(addr, old, old+incr));
+ while (AO_EXPECT_FALSE(!AO_compare_and_swap_acquire(addr, old, old+incr)));
return old;
}
# define AO_HAVE_fetch_and_add_acquire
{
old = *addr;
}
- while (!AO_compare_and_swap_release(addr, old, old+incr));
+ while (AO_EXPECT_FALSE(!AO_compare_and_swap_release(addr, old, old+incr)));
return old;
}
# define AO_HAVE_fetch_and_add_release
{
old = *addr;
}
- while (!AO_compare_and_swap(addr, old, old+incr));
+ while (AO_EXPECT_FALSE(!AO_compare_and_swap(addr, old, old+incr)));
return old;
}
# define AO_HAVE_fetch_and_add
{
old = *addr;
}
- while (!AO_compare_and_swap_full(addr, old, old & value));
+ while (AO_EXPECT_FALSE(!AO_compare_and_swap_full(addr, old, old & value)));
}
# define AO_HAVE_and_full
#endif
{
old = *addr;
}
- while (!AO_compare_and_swap_full(addr, old, old | value));
+ while (AO_EXPECT_FALSE(!AO_compare_and_swap_full(addr, old, old | value)));
}
# define AO_HAVE_or_full
#endif
{
old = *addr;
}
- while (!AO_compare_and_swap_full(addr, old, old ^ value));
+ while (AO_EXPECT_FALSE(!AO_compare_and_swap_full(addr, old, old ^ value)));
}
# define AO_HAVE_xor_full
#endif
: "=&r"(result), "+m"(*addr)
: "r"(new_val), "r"(addr)
: "cc");
- } while (result);
+ } while (AO_EXPECT_FALSE(result));
return !result; /* if succeded, return 1 else 0 */
}
# define AO_HAVE_compare_double_and_swap_double
next = AO_load(list);
*x = next;
}
- while(!AO_compare_and_swap_release(list, next, x_bits));
+ while (AO_EXPECT_FALSE(!AO_compare_and_swap_release(list, next, x_bits)));
}
/*
/* We need to make sure that first is still the first entry on the */
/* list. Otherwise it's possible that a reinsertion of it was */
/* already started before we added the black list entry. */
- if (first != AO_load(list)) {
+ if (AO_EXPECT_FALSE(first != AO_load(list))) {
AO_store_release(a->AO_stack_bl+i, 0);
goto retry;
}
first_ptr = AO_REAL_NEXT_PTR(first);
next = AO_load(first_ptr);
- if (!AO_compare_and_swap_release(list, first, next)) {
+ if (AO_EXPECT_FALSE(!AO_compare_and_swap_release(list, first, next))) {
AO_store_release(a->AO_stack_bl+i, 0);
goto retry;
}
do {
next = AO_load(&(list -> ptr));
*element = next;
- } while (!AO_compare_and_swap_release
- ( &(list -> ptr), next, (AO_t) element));
+ } while (AO_EXPECT_FALSE(!AO_compare_and_swap_release(&(list -> ptr),
+ next, (AO_t)element)));
/* This uses a narrow CAS here, an old optimization suggested */
/* by Treiber. Pop is still safe, since we run into the ABA */
/* problem only if there were both intervening "pop"s and "push"es. */
cptr = (AO_t *)AO_load(&(list -> ptr));
if (cptr == 0) return 0;
next = *cptr;
- } while (!AO_compare_double_and_swap_double_release
- (list, cversion, (AO_t) cptr, cversion+1, (AO_t) next));
+ } while (AO_EXPECT_FALSE(!AO_compare_double_and_swap_double_release(list,
+ cversion, (AO_t)cptr,
+ cversion+1, (AO_t)next)));
return cptr;
}