From 2a7e191dd8368db807af3d6ea184e440d411f313 Mon Sep 17 00:00:00 2001 From: Nathan Hjelm Date: Tue, 14 Jul 2015 12:12:59 -0600 Subject: [PATCH] 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 --- opal/class/opal_fifo.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/opal/class/opal_fifo.h b/opal/class/opal_fifo.h index 79ba5bae6b..604601dc35 100644 --- a/opal/class/opal_fifo.h +++ b/opal/class/opal_fifo.h @@ -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)) {