summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2022-02-20 10:51:25 +0300
committerIvan Maidanski <ivmai@mail.ru>2022-08-12 00:20:02 +0300
commitae0f8e7e4081c10b1febfa9c481925a666dd8e23 (patch)
tree40f06558f9f33bcc792cbe9a72a0fc6b8511e94e
parent8e6d7787d438a1ec8d767230537d894cac5af88a (diff)
downloadlibatomic_ops-ae0f8e7e4081c10b1febfa9c481925a666dd8e23.tar.gz
Repeat black list check on CAS fail in stack_push_explicit_aux_release
(a cherry-pick of commit aecb72063 from 'master') Also, execute the first read in a loop with an acquire barrier, and place black list checking as close to CAS as possible. * src/atomic_ops_stack.c [AO_USE_ALMOST_LOCK_FREE] (AO_stack_push_explicit_aux_release): Use acquire barrier to read list value (stored to next local variable); read list value and store it to x element before iterating over AO_stack_bl (and, thus, retry iterating over AO_stack_bl if CAS failed).
-rw-r--r--src/atomic_ops_stack.c10
1 files changed, 4 insertions, 6 deletions
diff --git a/src/atomic_ops_stack.c b/src/atomic_ops_stack.c
index 5d7995f..c31c7bf 100644
--- a/src/atomic_ops_stack.c
+++ b/src/atomic_ops_stack.c
@@ -67,6 +67,9 @@ void AO_stack_push_explicit_aux_release(volatile AO_t *list, AO_t *x,
/* No deletions of x can start here, since x is not currently in the */
/* list. */
retry:
+ do {
+ next = AO_load_acquire(list);
+ store_before_cas(x, next);
# if AO_BL_SIZE == 2
{
/* Start all loads as close to concurrently as possible. */
@@ -102,12 +105,7 @@ void AO_stack_push_explicit_aux_release(volatile AO_t *list, AO_t *x,
}
# endif
/* x_bits is not currently being deleted */
- do
- {
- next = AO_load(list);
- store_before_cas(x, next);
- }
- while (AO_EXPECT_FALSE(!AO_compare_and_swap_release(list, next, x_bits)));
+ } while (AO_EXPECT_FALSE(!AO_compare_and_swap_release(list, next, x_bits)));
}
/*