* Add '-no-undefined' to LDFLAGS in src/Makefile.am.
* Add AO_and, AO_xor atomic operations.
+* Add AO_fetch_compare_and_swap primitives.
* Add and fill in AUTHORS, TODO files.
* Add atomic_ops.pc.in and atomic_ops-uninstalled.pc.in to pkgconfig folder.
* Adjust AO_..._H macros in public headers.
TODO tasks
==========
-Add equivalent of __sync_val_compare_and_swap. Add tests.
-
Add C++0x ATM (atomic memory operations) layer.
Atomically compare *addr to old_val, and replace *addr by new_val
if the first comparison succeeds. Returns nonzero if the comparison
succeeded and *addr was updated.
+AO_t fetch_compare_and_swap(volatile AO_t * addr, AO_t old_val, AO_t new_val)
+ Atomically compare *addr to old_val, and replace *addr by new_val
+ if the first comparison succeeds; returns the original value of *addr.
AO_TS_VAL_t test_and_set(volatile AO_TS_t * addr)
Atomically read the binary value at *addr, and set it. AO_TS_VAL_t
is an enumeration type which includes two values AO_TS_SET and
sigset_t old_sigs;
block_all_signals(&old_sigs);
# endif
+
lock(my_lock);
if (*addr == old)
{
return result;
}
+/* FIXME: implement AO_fetch_compare_and_swap */
+
int AO_compare_double_and_swap_double_emulation(volatile AO_double_t *addr,
AO_t old_val1, AO_t old_val2,
AO_t new_val1, AO_t new_val2)
/* AO_or */
/* AO_xor */
/* AO_compare_and_swap */
+/* AO_fetch_compare_and_swap */
/* */
/* Note that atomicity guarantees are valid only if both */
/* readers and writers use AO_ operations to access the */
/* or can only be read concurrently, then x can be accessed */
/* via ordinary references and assignments. */
/* */
-/* Compare_and_exchange takes an address and an expected old */
-/* value and a new value, and returns an int. Nonzero */
+/* AO_compare_and_swap takes an address and an expected old */
+/* value and a new value, and returns an int. Non-zero result */
/* indicates that it succeeded. */
+/* AO_fetch_compare_and_swap takes an address and an expected */
+/* old value and a new value, and returns the real old value. */
+/* The operation succeeded if and only if the expected old */
+/* value matches the old value returned. */
+/* */
/* Test_and_set takes an address, atomically replaces it by */
/* AO_TS_SET, and returns the prior value. */
/* An AO_TS_t location can be reset with the */
# else
# error Cannot implement AO_compare_and_swap_full on this architecture.
# endif
+/* FIXME: same for AO_fetch_compare_and_swap */
#endif /* AO_REQUIRE_CAS && !AO_HAVE_compare_and_swap ... */
/* The most common way to clear a test-and-set location */
# endif
#endif /* AO_HAVE_compare_and_swap_full */
+/* FIXME: implement AO_fetch_compare_and_swap */
+
#if !defined(AO_HAVE_compare_and_swap) \
&& defined(AO_HAVE_compare_and_swap_release)
# define AO_compare_and_swap(addr,old,new_val) \
# define AO_HAVE_int_compare_and_swap
#endif
+/* FIXME: implement AO_fetch_compare_and_swap */
+
/* AO_load */
#if defined(AO_HAVE_load_acquire) \
&& !defined(AO_HAVE_int_load_acquire)
}
#define AO_HAVE_compare_and_swap
+/* FIXME: implement AO_fetch_compare_and_swap */
+
/* helper functions for the Realview compiler: LDREXD is not usable
* with inline assembler, so use the "embedded" assembler as
* suggested by ARM Dev. support (June 2008). */
# define AO_HAVE_compare_double_and_swap_double_full
#endif
+/* FIXME: implement AO_fetch_compare_and_swap */
+
#undef AO_store
#undef AO_HAVE_store
#undef AO_store_write
return (int)was_equal;
}
#define AO_HAVE_compare_and_swap
+
+/* FIXME: implement AO_fetch_compare_and_swap */
}
#define AO_HAVE_compare_and_swap
+/* FIXME: implement AO_fetch_compare_and_swap */
+
#if !defined(__ARM_ARCH_6__) && !defined(__ARM_ARCH_6J__) \
&& !defined(__ARM_ARCH_6T2__) && !defined(__ARM_ARCH_6Z__) \
&& !defined(__ARM_ARCH_6ZT2__) && (!defined(__thumb__) \
return (int)ret;
}
#define AO_HAVE_compare_and_swap_full
+
+/* FIXME: implement AO_fetch_compare_and_swap */
}
#define AO_HAVE_compare_and_swap
+/* FIXME: implement AO_fetch_compare_and_swap */
+
#include "../ao_t_is_int.h"
}
#define AO_HAVE_compare_and_swap_release
+/* FIXME: implement AO_fetch_compare_and_swap */
+
AO_INLINE int
AO_char_compare_and_swap_acquire(volatile unsigned char *addr,
unsigned char old, unsigned char new_val)
}
#define AO_HAVE_compare_and_swap_full
+/* FIXME: implement AO_fetch_compare_and_swap */
+
#include "../ao_t_is_int.h"
}
#define AO_HAVE_compare_and_swap_full
+/* FIXME: implement AO_fetch_compare_and_swap */
+
/*
* FIXME: We should also implement fetch_and_add and or primitives
* directly.
}
#define AO_HAVE_compare_and_swap_full
+/* FIXME: implement AO_fetch_compare_and_swap */
+
AO_INLINE AO_t
AO_fetch_and_add(volatile AO_t *addr, AO_t incr) {
AO_t oldval;
}
#define AO_HAVE_compare_and_swap_full
+/* FIXME: implement AO_fetch_compare_and_swap */
+
/* FIXME: Add double-wide compare-and-swap for 32-bit executables. */
#define AO_HAVE_compare_and_swap_full
#endif /* !AO_NO_SPARC_V9 */
+/* FIXME: implement AO_fetch_compare_and_swap */
+
/* FIXME: This needs to be extended for SPARC v8 and v9. */
/* SPARC V8 also has swap. V9 has CAS. */
/* There are barriers like membar #LoadStore. */
}
#define AO_HAVE_compare_and_swap_full
+/* FIXME: implement AO_fetch_compare_and_swap */
+
/* Returns nonzero if the comparison succeeded. */
/* Really requires at least a Pentium. */
AO_INLINE int
}
#define AO_HAVE_compare_and_swap_full
+/* FIXME: implement AO_fetch_compare_and_swap */
+
#ifdef AO_CMPXCHG16B_AVAILABLE
/* NEC LE-IT: older AMD Opterons are missing this instruction.
}
#define AO_HAVE_compare_and_swap_full
+/* FIXME: implement AO_fetch_compare_and_swap */
+
/* Unlike real architectures, we define both double-width CAS variants. */
typedef struct {
}
#define AO_HAVE_compare_and_swap_release
+/* FIXME: implement AO_fetch_compare_and_swap */
+
AO_INLINE int
AO_char_compare_and_swap_acquire(volatile unsigned char *addr,
unsigned char old, unsigned char new_val)
}
#define AO_HAVE_compare_and_swap_full
-/* FIXME: We should also implement fetch_and_add and or primitives */
-/* directly. */
+/* FIXME: We should also implement AO_fetch_compare_and_swap, */
+/* AO_fetch_and_add, AO_and/or/xor primitives directly. */
}
#define AO_HAVE_compare_and_swap_release
+/* FIXME: implement AO_fetch_compare_and_swap */
+
AO_INLINE int
AO_char_compare_and_swap_acquire(volatile unsigned char *addr,
unsigned char old, unsigned char new_val)
# endif
}
# define AO_HAVE_compare_and_swap_full
+
+/* FIXME: implement AO_fetch_compare_and_swap */
#endif /* AO_ASSUME_WINDOWS98 */
}
#define AO_HAVE_compare_and_swap_full
+/* FIXME: implement AO_fetch_compare_and_swap */
+
/* As far as we can tell, the lfence and sfence instructions are not */
/* currently needed or useful for cached memory accesses. */
}
#define AO_HAVE_compare_and_swap_full
+/* FIXME: implement AO_fetch_compare_and_swap */
+
#if 0
/* FIXME: not tested (and probably wrong). Besides, */
/* it tickles a bug in Sun C 5.10 (when optimizing). */
}
#define AO_HAVE_compare_and_swap_full
+/* FIXME: implement AO_fetch_compare_and_swap */
+
#ifdef AO_CMPXCHG16B_AVAILABLE
/* NEC LE-IT: older AMD Opterons are missing this instruction.
* On these machines SIGILL will be thrown.
# else
"No AO_compare_and_swapXX";
# endif
+/* FIXME: test AO_fetch_compare_and_swap */
}
MISSING(AO_compare_and_swap);
if (x == 13) x = 42;
# endif
+/* FIXME: test AO_fetch_compare_and_swap */
# if defined(AO_HAVE_orXX)
AO_orXX(&x, 66);
TA_assert(x == 106);