the val1 field. AO_double_t exists only if AO_HAVE_double_t
is defined.
+Please note that AO_double_t (and AO_stack_t) variables should be properly
+aligned (8-byte alignment on 32-bit targets, 16-byte alignment on 64-bit ones)
+otherwise the behavior of a double-wide atomic primitive might be undefined
+(or an assertion violation might occur) if such a misaligned variable is
+passed (as a reference) to the primitive. Global and static variables should
+already have proper alignment automatically but automatic variables (i.e.
+located on the stack) might be misaligned because the stack might be
+word-aligned (e.g. 4-byte stack alignment is the default one for x86).
+Luckily, stack-allocated AO variables is a rare case in practice.
+
ORDERING CONSTRAINTS:
Each operation name also includes a suffix that specifies the associated
} AO_double_t;
#define AO_HAVE_double_t
+/* Note: AO_double_t volatile variables are not intended to be local */
+/* ones (at least those which are passed to AO double-wide primitives */
+/* as the first argument), otherwise it is the client responsibility to */
+/* ensure they have double-word alignment. */
+
/* Dummy declaration as a compile-time assertion for AO_double_t size. */
struct AO_double_t_size_static_assert {
char dummy[sizeof(AO_double_t) == 2 * sizeof(AO_t) ? 1 : -1];
typedef volatile AO_double_t AO_stack_t;
/* AO_val1 is version, AO_val2 is pointer. */
+/* Note: AO_stack_t variables are not intended to be local ones, */
+/* otherwise it is the client responsibility to ensure they have */
+/* double-word alignment. */
#define AO_STACK_INITIALIZER AO_DOUBLE_T_INITIALIZER
# if defined(AO_HAVE_double_compare_and_swapXX) \
|| defined(AO_HAVE_double_loadXX) \
|| defined(AO_HAVE_double_storeXX)
- AO_double_t old_w;
+ static AO_double_t old_w; /* static to avoid misalignment */
AO_double_t new_w;
# endif
# if defined(AO_HAVE_compare_and_swap_doubleXX) \
|| defined(AO_HAVE_compare_double_and_swap_doubleXX) \
|| defined(AO_HAVE_double_compare_and_swapXX)
- AO_double_t w;
+ static AO_double_t w; /* static to avoid misalignment */
w.AO_val1 = 0;
w.AO_val2 = 0;
# endif