(Cherry-pick commit
c386add from 'release-7_4' branch.)
The failure is caused by violation of an assertion that checks
AO_double_t variable is 8-byte aligned on x86.
* doc/README.txt (AO_double_t): Add note about required alignment.
* src/atomic_ops/sysdeps/standard_ao_double_t.h (AO_double_t): Add
comment about alignment.
* src/atomic_ops_stack.h (AO_stack_t): Likewise.
* tests/test_atomic.template (test_atomicXX): Define w
local variable as static (as otherwise, e.g., it could have 4-byte
alignment on x86); add comment.
* tests/test_atomic_include.h: Regenerate.
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. */
+
#define AO_val1 AO_parts.AO_v1
#define AO_val2 AO_parts.AO_v2
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 {0}
AO_TS_t z = AO_TS_INITIALIZER;
# endif
# if defined(AO_HAVE_double_t)
- AO_double_t w;
+ static AO_double_t w; /* static to avoid misalignment */
w.AO_val1 = 0;
w.AO_val2 = 0;
# endif
AO_TS_t z = AO_TS_INITIALIZER;
# endif
# if defined(AO_HAVE_double_t)
- AO_double_t w;
+ static AO_double_t w; /* static to avoid misalignment */
w.AO_val1 = 0;
w.AO_val2 = 0;
# endif
AO_TS_t z = AO_TS_INITIALIZER;
# endif
# if defined(AO_HAVE_double_t)
- AO_double_t w;
+ static AO_double_t w; /* static to avoid misalignment */
w.AO_val1 = 0;
w.AO_val2 = 0;
# endif
AO_TS_t z = AO_TS_INITIALIZER;
# endif
# if defined(AO_HAVE_double_t)
- AO_double_t w;
+ static AO_double_t w; /* static to avoid misalignment */
w.AO_val1 = 0;
w.AO_val2 = 0;
# endif
AO_TS_t z = AO_TS_INITIALIZER;
# endif
# if defined(AO_HAVE_double_t)
- AO_double_t w;
+ static AO_double_t w; /* static to avoid misalignment */
w.AO_val1 = 0;
w.AO_val2 = 0;
# endif
AO_TS_t z = AO_TS_INITIALIZER;
# endif
# if defined(AO_HAVE_double_t)
- AO_double_t w;
+ static AO_double_t w; /* static to avoid misalignment */
w.AO_val1 = 0;
w.AO_val2 = 0;
# endif
AO_TS_t z = AO_TS_INITIALIZER;
# endif
# if defined(AO_HAVE_double_t)
- AO_double_t w;
+ static AO_double_t w; /* static to avoid misalignment */
w.AO_val1 = 0;
w.AO_val2 = 0;
# endif
AO_TS_t z = AO_TS_INITIALIZER;
# endif
# if defined(AO_HAVE_double_t)
- AO_double_t w;
+ static AO_double_t w; /* static to avoid misalignment */
w.AO_val1 = 0;
w.AO_val2 = 0;
# endif
AO_TS_t z = AO_TS_INITIALIZER;
# endif
# if defined(AO_HAVE_double_t)
- AO_double_t w;
+ static AO_double_t w; /* static to avoid misalignment */
w.AO_val1 = 0;
w.AO_val2 = 0;
# endif