diff --git a/include/ck_stack.h b/include/ck_stack.h index f71e515..4cc5024 100644 --- a/include/ck_stack.h +++ b/include/ck_stack.h @@ -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; }