ck_stack: Add fences for ABA-friendly push_mpmc.

ck_pring
Samy Al Bahra 10 years ago
parent fe589bd345
commit f95c2c2413

@ -197,10 +197,12 @@ ck_stack_pop_mpmc(struct ck_stack *target)
struct ck_stack original, update; struct ck_stack original, update;
original.generation = ck_pr_load_ptr(&target->generation); original.generation = ck_pr_load_ptr(&target->generation);
ck_pr_fence_load();
original.head = ck_pr_load_ptr(&target->head); original.head = ck_pr_load_ptr(&target->head);
if (original.head == NULL) if (original.head == NULL)
return NULL; return NULL;
/* Order with respect to next pointer. */
ck_pr_fence_load(); ck_pr_fence_load();
update.generation = original.generation + 1; update.generation = original.generation + 1;
@ -212,6 +214,7 @@ ck_stack_pop_mpmc(struct ck_stack *target)
update.generation = original.generation + 1; update.generation = original.generation + 1;
/* Order with respect to next pointer. */
ck_pr_fence_load(); ck_pr_fence_load();
update.head = original.head->next; update.head = original.head->next;
} }
@ -228,6 +231,7 @@ ck_stack_trypop_mpmc(struct ck_stack *target, struct ck_stack_entry **r)
struct ck_stack original, update; struct ck_stack original, update;
original.generation = ck_pr_load_ptr(&target->generation); original.generation = ck_pr_load_ptr(&target->generation);
ck_pr_fence_load();
original.head = ck_pr_load_ptr(&target->head); original.head = ck_pr_load_ptr(&target->head);
if (original.head == NULL) if (original.head == NULL)
return false; return false;
@ -271,7 +275,7 @@ ck_stack_push_mpnc(struct ck_stack *target, struct ck_stack_entry *entry)
struct ck_stack_entry *stack; struct ck_stack_entry *stack;
entry->next = NULL; entry->next = NULL;
ck_pr_fence_store(); ck_pr_fence_store_atomic();
stack = ck_pr_fas_ptr(&target->head, entry); stack = ck_pr_fas_ptr(&target->head, entry);
ck_pr_store_ptr(&entry->next, stack); ck_pr_store_ptr(&entry->next, stack);
ck_pr_fence_store(); ck_pr_fence_store();
@ -289,7 +293,6 @@ ck_stack_push_spnc(struct ck_stack *target, struct ck_stack_entry *entry)
entry->next = target->head; entry->next = target->head;
target->head = entry; target->head = entry;
return; return;
} }

Loading…
Cancel
Save