Skip to content

Commit a436af3

Browse files
committed
Avoid AO_stack_t to cross CPU cache line boundary
(a cherry-pick of commit ed712f7 from 'release-7_6') Issue bdwgc#45 (libatomic_ops). Enforce proper alignment of AO_stack_t.AO_ptr to avoid the structure value to cross the CPU cache line boundary. A workaround for almost-lock-free push/pop test failures on aarch64, at least. * src/atomic_ops_stack.h [AO_USE_ALMOST_LOCK_FREE && !AO_STACK_ATTR_ALLIGNED] (AO_STACK_ATTR_ALLIGNED): Define. * src/atomic_ops_stack.h [AO_USE_ALMOST_LOCK_FREE] (AO_stack_t.AO_ptr): Add AO_STACK_ATTR_ALLIGNED attribute.
1 parent 410ca73 commit a436af3

File tree

1 file changed

+31
-1
lines changed

1 file changed

+31
-1
lines changed

src/atomic_ops_stack.h

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,36 @@
8989
# error AO_BL_SIZE too big
9090
#endif
9191

92+
#ifndef AO_STACK_ATTR_ALLIGNED
93+
/* Enforce proper alignment of AO_stack_t.AO_ptr to avoid the */
94+
/* structure value to cross the CPU cache line boundary. */
95+
/* A workaround for almost-lock-free push/pop test failures */
96+
/* on aarch64, at least. */
97+
# if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)
98+
# define AO_STACK_LOG_BL_SZP1 \
99+
(AO_BL_SIZE > 7 ? 4 : AO_BL_SIZE > 3 ? 3 : AO_BL_SIZE > 1 ? 2 : 1)
100+
# define AO_STACK_ATTR_ALLIGNED \
101+
__attribute__((__aligned__(sizeof(AO_t) << AO_STACK_LOG_BL_SZP1)))
102+
# elif defined(_MSC_VER) && _MSC_VER >= 1400 /* Visual Studio 2005+ */
103+
/* MS compiler accepts only a literal number in align, not expression. */
104+
/* AO_STACK_ALLIGN_N is 1 << (AO_N_BITS + AO_STACK_LOG_BL_SZP1). */
105+
# if AO_N_BITS > 2 && AO_BL_SIZE > 7
106+
# define AO_STACK_ALLIGN_N 128
107+
# elif (AO_N_BITS > 2 && AO_BL_SIZE > 3) || AO_BL_SIZE > 7
108+
# define AO_STACK_ALLIGN_N 64
109+
# elif (AO_N_BITS > 2 && AO_BL_SIZE > 1) || AO_BL_SIZE > 3
110+
# define AO_STACK_ALLIGN_N 32
111+
# elif AO_N_BITS > 2 || AO_BL_SIZE > 1
112+
# define AO_STACK_ALLIGN_N 16
113+
# else
114+
# define AO_STACK_ALLIGN_N 8
115+
# endif
116+
# define AO_STACK_ATTR_ALLIGNED __declspec(align(AO_STACK_ALLIGN_N))
117+
# else
118+
# define AO_STACK_ATTR_ALLIGNED /* TODO: alignment is not enforced */
119+
# endif
120+
#endif /* !AO_STACK_ATTR_ALLIGNED */
121+
92122
typedef struct AO__stack_aux {
93123
volatile AO_t AO_stack_bl[AO_BL_SIZE];
94124
} AO_stack_aux;
@@ -114,7 +144,7 @@ AO_stack_pop_explicit_aux_acquire(volatile AO_t *list, AO_stack_aux *);
114144
/* And now AO_stack_t for the real interface: */
115145

116146
typedef struct AO__stack {
117-
volatile AO_t AO_ptr;
147+
AO_STACK_ATTR_ALLIGNED volatile AO_t AO_ptr;
118148
AO_stack_aux AO_aux;
119149
} AO_stack_t;
120150

0 commit comments

Comments
 (0)