ck_stack: Assume weak ordering of CAS.

I was actually unsure of the exact memory model
I wanted for atomic RMW operations. It was
made apparent with time that I had to adopt RMO
if I didn't want to sacrifice performance. Make
sure we can assume RMO for the stack.
ck_pring
Samy Al Bahra 13 years ago
parent 3f6a3660eb
commit 2d2b49a313

@ -56,10 +56,13 @@ ck_stack_push_upmc(struct ck_stack *target, struct ck_stack_entry *entry)
struct ck_stack_entry *stack;
stack = ck_pr_load_ptr(&target->head);
ck_pr_store_ptr(&entry->next, stack);
entry->next = stack;
ck_pr_fence_store();
while (ck_pr_cas_ptr_value(&target->head, stack, entry, &stack) == false)
ck_pr_store_ptr(&entry->next, stack);
while (ck_pr_cas_ptr_value(&target->head, stack, entry, &stack) == false) {
entry->next = stack;
ck_pr_fence_store();
}
return;
}
@ -77,7 +80,8 @@ ck_stack_trypush_upmc(struct ck_stack *target, struct ck_stack_entry *entry)
struct ck_stack_entry *stack;
stack = ck_pr_load_ptr(&target->head);
ck_pr_store_ptr(&entry->next, stack);
entry->next = stack;
ck_pr_fence_store();
return ck_pr_cas_ptr(&target->head, stack, entry);
}
@ -91,15 +95,20 @@ ck_stack_trypush_upmc(struct ck_stack *target, struct ck_stack_entry *entry)
CK_CC_INLINE static struct ck_stack_entry *
ck_stack_pop_upmc(struct ck_stack *target)
{
struct ck_stack_entry *entry;
struct ck_stack_entry *entry, *next;
entry = ck_pr_load_ptr(&target->head);
if (entry == NULL)
return (NULL);
while (ck_pr_cas_ptr_value(&target->head, entry, entry->next, &entry) == false) {
ck_pr_fence_load();
next = entry->next;
while (ck_pr_cas_ptr_value(&target->head, entry, next, &entry) == false) {
if (entry == NULL)
break;
ck_pr_fence_load();
next = entry->next;
}
return (entry);
@ -123,6 +132,7 @@ ck_stack_trypop_upmc(struct ck_stack *target, struct ck_stack_entry **r)
if (entry == NULL)
return false;
ck_pr_fence_load();
if (ck_pr_cas_ptr(&target->head, entry, entry->next) == true) {
*r = entry;
return true;
@ -143,6 +153,7 @@ ck_stack_batch_pop_upmc(struct ck_stack *target)
struct ck_stack_entry *entry;
entry = ck_pr_fas_ptr(&target->head, NULL);
ck_pr_fence_load();
return (entry);
}
#endif /* CK_F_STACK_BATCH_POP_UPMC */
@ -190,6 +201,8 @@ ck_stack_pop_mpmc(struct ck_stack *target)
if (original.head == NULL)
return (NULL);
ck_pr_fence_load();
update.generation = original.generation + 1;
update.head = original.head->next;
@ -197,8 +210,10 @@ ck_stack_pop_mpmc(struct ck_stack *target)
if (original.head == NULL)
return (NULL);
ck_pr_store_ptr(&update.generation, original.generation + 1);
ck_pr_store_ptr(&update.head, original.head->next);
update.generation = original.generation + 1;
ck_pr_fence_load();
update.head = original.head->next;
}
return (original.head);
@ -218,6 +233,7 @@ ck_stack_trypop_mpmc(struct ck_stack *target, struct ck_stack_entry **r)
return false;
update.generation = original.generation + 1;
ck_pr_fence_load();
update.head = original.head->next;
if (ck_pr_cas_ptr_2_value(target, &original, &update, &original) == true) {
@ -316,9 +332,7 @@ ck_stack_init(struct ck_stack *stack)
{
stack->head = NULL;
stack->generation = 0;
ck_pr_fence_store();
stack->generation = NULL;
return;
}

Loading…
Cancel
Save