This reverts commit
69c4010c1b3d43e2e179421e27379aaa5aeeb6d8.
The failure is actually caused by the fact that default alignment of
stack on x86 is 4 bytes.
So, another solution should be proposed to fix the issue for other
compilers (and, potentially, other targets). E.g. do not place
AO_double_t volatile variables on stack.
If the client defines AO_ASSUME_VISTA (before include atomic_ops.h), it should
make double_compare_and_swap_full available.
-Please note that MS compiler for x86 does not align AO_double_t on an 8-byte
-boundary, thus to avoid an undefined behavior, an AO_double_t (volatile)
-variable should be declared with AO_DOUBLE_ALIGN attribute if the variable
-reference is passed to an AO primitive (the attribute is not applicable to
-arguments and pointers).
Note that the library is covered by the GNU General Public License, while
the top 2 of these pieces allow use in proprietary code.
AO_t AO_val2;
} AO_double_t;
#define AO_HAVE_double_t
-#define AO_DOUBLE_ALIGN /* empty */
#define AO_DOUBLE_T_INITIALIZER { (AO_t)0, (AO_t)0 }
typedef __m128 double_ptr_storage;
#elif defined(_WIN32) && !defined(__GNUC__)
typedef unsigned __int64 double_ptr_storage;
-# ifdef _MSC_VER
- /* VC++/x86 does not align __int64 properly by default, thus, */
- /* causing an undefined behavior or assertions violation in */
- /* the double-wide atomic primitives. For the proper alignment, */
- /* all variables of AO_double_t type (in the client code) those */
- /* address is passed to an AO primitive should be defined with the */
- /* given attribute. Not a part of double_ptr_storage because the */
- /* attribute cannot be applied to function parameters. */
-# define AO_DOUBLE_ALIGN __declspec(align(8))
-# endif
#else
typedef unsigned long long double_ptr_storage;
#endif
# define AO_HAVE_DOUBLE_PTR_STORAGE
-#ifndef AO_DOUBLE_ALIGN
-# define AO_DOUBLE_ALIGN /* empty */
-#endif
-
typedef union {
struct { AO_t AO_v1; AO_t AO_v2; } AO_parts;
/* Note that AO_v1 corresponds to the low or the high part of */
/* Object free lists. Ith entry corresponds to objects */
/* of total size 2**i bytes. */
-AO_stack_t AO_DOUBLE_ALIGN AO_free_list[LOG_MAX_SIZE+1];
+AO_stack_t AO_free_list[LOG_MAX_SIZE+1];
/* Break up the chunk, and add it to the object free list for */
/* the given size. We have exclusive access to chunk. */
AO_stack_pop_explicit_aux_acquire(&((l)->AO_ptr), &((l)->AO_aux))
#define AO_HAVE_stack_pop_acquire
-#ifndef AO_DOUBLE_ALIGN
- /* For AO_stack clients only. */
-# define AO_DOUBLE_ALIGN /* empty */
-#endif
-
# else /* Use fully non-blocking data structure, wide CAS */
#ifndef AO_HAVE_double_t
typedef volatile AO_double_t AO_stack_t;
/* AO_val1 is version, AO_val2 is pointer. */
-/* AO_stack_t variables should have AO_DOUBLE_ALIGN attribute. */
#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 AO_DOUBLE_ALIGN old_w;
+ AO_double_t old_w;
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 AO_DOUBLE_ALIGN w;
+ AO_double_t w;
w.AO_val1 = 0;
w.AO_val2 = 0;
# endif
int data;
} list_element;
-AO_stack_t AO_DOUBLE_ALIGN the_list = AO_STACK_INITIALIZER;
+AO_stack_t the_list = AO_STACK_INITIALIZER;
void add_elements(int n)
{