opal/fifo: if available use load-linked store-conditional
These instructions allow a more efficient implementation of the opal_fifo_pop_atomic function. Signed-off-by: Nathan Hjelm <hjelmn@lanl.gov>
Этот коммит содержится в:
родитель
6a19a10fbb
Коммит
2a7e191dd8
@ -216,6 +216,27 @@ static inline opal_list_item_t *opal_fifo_pop_atomic (opal_fifo_t *fifo)
|
||||
{
|
||||
opal_list_item_t *item, *next;
|
||||
|
||||
#if OPAL_HAVE_ATOMIC_LLSC_PTR
|
||||
/* use load-linked store-conditional to avoid ABA issues */
|
||||
do {
|
||||
item = opal_atomic_ll_ptr (&fifo->opal_fifo_head.data.item);
|
||||
if (&fifo->opal_fifo_ghost == item) {
|
||||
if (&fifo->opal_fifo_ghost == fifo->opal_fifo_tail.data.item) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* fifo does not appear empty. wait for the fifo to be made
|
||||
* consistent by conflicting thread. */
|
||||
continue;
|
||||
}
|
||||
|
||||
next = (opal_list_item_t *) item->opal_list_next;
|
||||
if (opal_atomic_sc_ptr (&fifo->opal_fifo_head.data.item, next)) {
|
||||
break;
|
||||
}
|
||||
} while (1);
|
||||
#else
|
||||
/* protect against ABA issues by "locking" the head */
|
||||
do {
|
||||
if (opal_atomic_cmpset_32 ((int32_t *) &fifo->opal_fifo_head.data.counter, 0, 1)) {
|
||||
break;
|
||||
@ -234,6 +255,7 @@ static inline opal_list_item_t *opal_fifo_pop_atomic (opal_fifo_t *fifo)
|
||||
|
||||
next = (opal_list_item_t *) item->opal_list_next;
|
||||
fifo->opal_fifo_head.data.item = next;
|
||||
#endif
|
||||
|
||||
if (&fifo->opal_fifo_ghost == next) {
|
||||
if (!opal_atomic_cmpset_ptr (&fifo->opal_fifo_tail.data.item, item, &fifo->opal_fifo_ghost)) {
|
||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user