1212 * All rights reserved.
1313 * Copyright (c) 2007 Voltaire All rights reserved.
1414 * Copyright (c) 2010 IBM Corporation. All rights reserved.
15- * Copyright (c) 2014-2016 Los Alamos National Security, LLC. All rights
15+ * Copyright (c) 2014-2018 Los Alamos National Security, LLC. All rights
1616 * reseved.
1717 * $COPYRIGHT$
1818 *
@@ -186,9 +186,10 @@ static inline opal_list_item_t *opal_fifo_pop_atomic (opal_fifo_t *fifo)
186186static inline opal_list_item_t * opal_fifo_push_atomic (opal_fifo_t * fifo ,
187187 opal_list_item_t * item )
188188{
189+ const opal_list_item_t * const ghost = & fifo -> opal_fifo_ghost ;
189190 opal_list_item_t * tail_item ;
190191
191- item -> opal_list_next = & fifo -> opal_fifo_ghost ;
192+ item -> opal_list_next = ( opal_list_item_t * ) ghost ;
192193
193194 opal_atomic_wmb ();
194195
@@ -197,7 +198,7 @@ static inline opal_list_item_t *opal_fifo_push_atomic (opal_fifo_t *fifo,
197198
198199 opal_atomic_wmb ();
199200
200- if (& fifo -> opal_fifo_ghost == tail_item ) {
201+ if (ghost == tail_item ) {
201202 /* update the head */
202203 fifo -> opal_fifo_head .data .item = item ;
203204 } else {
@@ -215,14 +216,24 @@ static inline opal_list_item_t *opal_fifo_push_atomic (opal_fifo_t *fifo,
215216 */
216217static inline opal_list_item_t * opal_fifo_pop_atomic (opal_fifo_t * fifo )
217218{
218- opal_list_item_t * item , * next ;
219+ const opal_list_item_t * const ghost = & fifo -> opal_fifo_ghost ;
219220
220221#if OPAL_HAVE_ATOMIC_LLSC_PTR
222+ register opal_list_item_t * item , * next ;
223+ int attempt = 0 , ret = 0 ;
224+
221225 /* use load-linked store-conditional to avoid ABA issues */
222226 do {
223- item = opal_atomic_ll_ptr (& fifo -> opal_fifo_head .data .item );
224- if (& fifo -> opal_fifo_ghost == item ) {
225- if (& fifo -> opal_fifo_ghost == fifo -> opal_fifo_tail .data .item ) {
227+ if (++ attempt == 5 ) {
228+ /* deliberatly suspend this thread to allow other threads to run. this should
229+ * only occur during periods of contention on the lifo. */
230+ _opal_lifo_release_cpu ();
231+ attempt = 0 ;
232+ }
233+
234+ opal_atomic_ll_ptr (& fifo -> opal_fifo_head .data .item , item );
235+ if (ghost == item ) {
236+ if (ghost == fifo -> opal_fifo_tail .data .item ) {
226237 return NULL ;
227238 }
228239
@@ -232,11 +243,12 @@ static inline opal_list_item_t *opal_fifo_pop_atomic (opal_fifo_t *fifo)
232243 }
233244
234245 next = (opal_list_item_t * ) item -> opal_list_next ;
235- if (opal_atomic_sc_ptr (& fifo -> opal_fifo_head .data .item , next )) {
236- break ;
237- }
238- } while (1 );
246+ opal_atomic_sc_ptr (& fifo -> opal_fifo_head .data .item , next , ret );
247+ } while (!ret );
248+
239249#else
250+ opal_list_item_t * item , * next ;
251+
240252 /* protect against ABA issues by "locking" the head */
241253 do {
242254 if (opal_atomic_cmpset_32 ((int32_t * ) & fifo -> opal_fifo_head .data .counter , 0 , 1 )) {
@@ -258,9 +270,9 @@ static inline opal_list_item_t *opal_fifo_pop_atomic (opal_fifo_t *fifo)
258270 fifo -> opal_fifo_head .data .item = next ;
259271#endif
260272
261- if (& fifo -> opal_fifo_ghost == next ) {
262- if (!opal_atomic_cmpset_ptr (& fifo -> opal_fifo_tail .data .item , item , & fifo -> opal_fifo_ghost )) {
263- while (& fifo -> opal_fifo_ghost == item -> opal_list_next ) {
273+ if (ghost == next ) {
274+ if (!opal_atomic_cmpset_ptr (& fifo -> opal_fifo_tail .data .item , item , ( void * ) ghost )) {
275+ while (ghost == item -> opal_list_next ) {
264276 opal_atomic_rmb ();
265277 }
266278
0 commit comments