ck_hp: hp_acquire patterns require strict fences under TSO.

Several counter-examples were found which break in the
presence of store-to-load re-ordering. Strict fence
semantics are necessary.

Thanks to Paul McKenney for helpful discussions.
ck_pring
Samy Al Bahra 12 years ago
parent c22dcdb04b
commit 5c483e3b1c

@ -81,7 +81,7 @@ ck_hp_fifo_enqueue_mpmc(ck_hp_record_t *record,
for (;;) { for (;;) {
tail = ck_pr_load_ptr(&fifo->tail); tail = ck_pr_load_ptr(&fifo->tail);
ck_hp_set(record, 0, tail); ck_hp_set(record, 0, tail);
ck_pr_fence_memory(); ck_pr_fence_strict_memory();
if (tail != ck_pr_load_ptr(&fifo->tail)) if (tail != ck_pr_load_ptr(&fifo->tail))
continue; continue;
@ -112,7 +112,7 @@ ck_hp_fifo_tryenqueue_mpmc(ck_hp_record_t *record,
tail = ck_pr_load_ptr(&fifo->tail); tail = ck_pr_load_ptr(&fifo->tail);
ck_hp_set(record, 0, tail); ck_hp_set(record, 0, tail);
ck_pr_fence_memory(); ck_pr_fence_strict_memory();
if (tail != ck_pr_load_ptr(&fifo->tail)) if (tail != ck_pr_load_ptr(&fifo->tail))
return false; return false;
@ -140,13 +140,13 @@ ck_hp_fifo_dequeue_mpmc(ck_hp_record_t *record,
ck_pr_fence_load(); ck_pr_fence_load();
tail = ck_pr_load_ptr(&fifo->tail); tail = ck_pr_load_ptr(&fifo->tail);
ck_hp_set(record, 0, head); ck_hp_set(record, 0, head);
ck_pr_fence_memory(); ck_pr_fence_strict_memory();
if (head != ck_pr_load_ptr(&fifo->head)) if (head != ck_pr_load_ptr(&fifo->head))
continue; continue;
next = ck_pr_load_ptr(&head->next); next = ck_pr_load_ptr(&head->next);
ck_hp_set(record, 1, next); ck_hp_set(record, 1, next);
ck_pr_fence_memory(); ck_pr_fence_strict_memory();
if (head != ck_pr_load_ptr(&fifo->head)) if (head != ck_pr_load_ptr(&fifo->head))
continue; continue;
@ -175,13 +175,13 @@ ck_hp_fifo_trydequeue_mpmc(ck_hp_record_t *record,
ck_pr_fence_load(); ck_pr_fence_load();
tail = ck_pr_load_ptr(&fifo->tail); tail = ck_pr_load_ptr(&fifo->tail);
ck_hp_set(record, 0, head); ck_hp_set(record, 0, head);
ck_pr_fence_memory(); ck_pr_fence_strict_memory();
if (head != ck_pr_load_ptr(&fifo->head)) if (head != ck_pr_load_ptr(&fifo->head))
return NULL; return NULL;
next = ck_pr_load_ptr(&head->next); next = ck_pr_load_ptr(&head->next);
ck_hp_set(record, 1, next); ck_hp_set(record, 1, next);
ck_pr_fence_memory(); ck_pr_fence_strict_memory();
if (head != ck_pr_load_ptr(&fifo->head)) if (head != ck_pr_load_ptr(&fifo->head))
return NULL; return NULL;

@ -62,7 +62,7 @@ ck_hp_stack_pop_mpmc(ck_hp_record_t *record, struct ck_stack *target)
return (NULL); return (NULL);
ck_hp_set(record, 0, entry); ck_hp_set(record, 0, entry);
ck_pr_fence_memory(); ck_pr_fence_strict_memory();
} while (entry != ck_pr_load_ptr(&target->head)); } while (entry != ck_pr_load_ptr(&target->head));
while (ck_pr_cas_ptr_value(&target->head, entry, entry->next, &entry) == false) { while (ck_pr_cas_ptr_value(&target->head, entry, entry->next, &entry) == false) {
@ -70,11 +70,11 @@ ck_hp_stack_pop_mpmc(ck_hp_record_t *record, struct ck_stack *target)
return (NULL); return (NULL);
ck_hp_set(record, 0, entry); ck_hp_set(record, 0, entry);
ck_pr_fence_memory(); ck_pr_fence_strict_memory();
update = ck_pr_load_ptr(&target->head); update = ck_pr_load_ptr(&target->head);
while (entry != update) { while (entry != update) {
ck_hp_set(record, 0, update); ck_hp_set(record, 0, update);
ck_pr_fence_memory(); ck_pr_fence_strict_memory();
entry = update; entry = update;
update = ck_pr_load_ptr(&target->head); update = ck_pr_load_ptr(&target->head);
if (update == NULL) if (update == NULL)
@ -95,7 +95,7 @@ ck_hp_stack_trypop_mpmc(ck_hp_record_t *record, struct ck_stack *target, struct
return false; return false;
ck_hp_set(record, 0, entry); ck_hp_set(record, 0, entry);
ck_pr_fence_memory(); ck_pr_fence_strict_memory();
if (entry != ck_pr_load_ptr(&target->head)) if (entry != ck_pr_load_ptr(&target->head))
goto leave; goto leave;

Loading…
Cancel
Save