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-2017 Los Alamos National Security, LLC. All rights
1616 * reseved.
1717 * $COPYRIGHT$
1818 *
@@ -85,14 +85,12 @@ static inline bool opal_fifo_is_empty( opal_fifo_t* fifo )
8585static inline opal_list_item_t * opal_fifo_push_atomic (opal_fifo_t * fifo ,
8686 opal_list_item_t * item )
8787{
88- opal_counted_pointer_t tail ;
88+ opal_counted_pointer_t tail = {. value = fifo -> opal_fifo_tail . value } ;
8989
9090 item -> opal_list_next = & fifo -> opal_fifo_ghost ;
9191
9292 do {
93- tail .value = fifo -> opal_fifo_tail .value ;
94-
95- if (opal_update_counted_pointer (& fifo -> opal_fifo_tail , tail , item )) {
93+ if (opal_update_counted_pointer (& fifo -> opal_fifo_tail , & tail , item )) {
9694 break ;
9795 }
9896 } while (1 );
@@ -102,7 +100,7 @@ static inline opal_list_item_t *opal_fifo_push_atomic (opal_fifo_t *fifo,
102100 if (& fifo -> opal_fifo_ghost == tail .data .item ) {
103101 /* update the head */
104102 opal_counted_pointer_t head = {.value = fifo -> opal_fifo_head .value };
105- opal_update_counted_pointer (& fifo -> opal_fifo_head , head , item );
103+ opal_update_counted_pointer (& fifo -> opal_fifo_head , & head , item );
106104 } else {
107105 /* update previous item */
108106 tail .data .item -> opal_list_next = item ;
@@ -116,44 +114,43 @@ static inline opal_list_item_t *opal_fifo_push_atomic (opal_fifo_t *fifo,
116114 */
117115static inline opal_list_item_t * opal_fifo_pop_atomic (opal_fifo_t * fifo )
118116{
119- opal_list_item_t * item , * next ;
120- opal_counted_pointer_t head , tail ;
117+ opal_list_item_t * item , * next , * ghost = & fifo -> opal_fifo_ghost ;
118+ opal_counted_pointer_t head = {. value = fifo -> opal_fifo_head . value } , tail ;
121119
122120 do {
123- head .value = fifo -> opal_fifo_head .value ;
124121 tail .value = fifo -> opal_fifo_tail .value ;
125122 opal_atomic_rmb ();
126123
127124 item = (opal_list_item_t * ) head .data .item ;
128125 next = (opal_list_item_t * ) item -> opal_list_next ;
129126
130- if (& fifo -> opal_fifo_ghost == tail .data .item && & fifo -> opal_fifo_ghost == item ) {
127+ if (ghost == tail .data .item && ghost == item ) {
131128 return NULL ;
132129 }
133130
134131 /* the head or next pointer are in an inconsistent state. keep looping. */
135- if (tail .data .item != item && & fifo -> opal_fifo_ghost != tail .data .item &&
136- & fifo -> opal_fifo_ghost == next ) {
132+ if (tail .data .item != item && ghost != tail .data .item && ghost == next ) {
133+ head . value = fifo -> opal_fifo_head . value ;
137134 continue ;
138135 }
139136
140137 /* try popping the head */
141- if (opal_update_counted_pointer (& fifo -> opal_fifo_head , head , next )) {
138+ if (opal_update_counted_pointer (& fifo -> opal_fifo_head , & head , next )) {
142139 break ;
143140 }
144141 } while (1 );
145142
146143 opal_atomic_wmb ();
147144
148145 /* check for tail and head consistency */
149- if (& fifo -> opal_fifo_ghost == next ) {
146+ if (ghost == next ) {
150147 /* the head was just set to &fifo->opal_fifo_ghost. try to update the tail as well */
151- if (!opal_update_counted_pointer (& fifo -> opal_fifo_tail , tail , & fifo -> opal_fifo_ghost )) {
148+ if (!opal_update_counted_pointer (& fifo -> opal_fifo_tail , & tail , ghost )) {
152149 /* tail was changed by a push operation. wait for the item's next pointer to be se then
153150 * update the head */
154151
155152 /* wait for next pointer to be updated by push */
156- while (& fifo -> opal_fifo_ghost == item -> opal_list_next ) {
153+ while (ghost == item -> opal_list_next ) {
157154 opal_atomic_rmb ();
158155 }
159156
@@ -166,7 +163,7 @@ static inline opal_list_item_t *opal_fifo_pop_atomic (opal_fifo_t *fifo)
166163 head .value = fifo -> opal_fifo_head .value ;
167164 next = (opal_list_item_t * ) item -> opal_list_next ;
168165
169- assert (& fifo -> opal_fifo_ghost == head .data .item );
166+ assert (ghost == head .data .item );
170167
171168 fifo -> opal_fifo_head .data .item = next ;
172169 opal_atomic_wmb ();
@@ -215,14 +212,14 @@ static inline opal_list_item_t *opal_fifo_push_atomic (opal_fifo_t *fifo,
215212 */
216213static inline opal_list_item_t * opal_fifo_pop_atomic (opal_fifo_t * fifo )
217214{
218- opal_list_item_t * item , * next ;
215+ opal_list_item_t * item , * next , * ghost = & fifo -> opal_fifo_ghost ;
219216
220217#if OPAL_HAVE_ATOMIC_LLSC_PTR
221218 /* use load-linked store-conditional to avoid ABA issues */
222219 do {
223220 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 ) {
221+ if (ghost == item ) {
222+ if (ghost == fifo -> opal_fifo_tail .data .item ) {
226223 return NULL ;
227224 }
228225
@@ -239,7 +236,7 @@ static inline opal_list_item_t *opal_fifo_pop_atomic (opal_fifo_t *fifo)
239236#else
240237 /* protect against ABA issues by "locking" the head */
241238 do {
242- if (opal_atomic_bool_cmpset_32 ((int32_t * ) & fifo -> opal_fifo_head .data .counter , 0 , 1 )) {
239+ if (! opal_atomic_swap_32 ((volatile int32_t * ) & fifo -> opal_fifo_head .data .counter , 1 )) {
243240 break ;
244241 }
245242
@@ -249,7 +246,7 @@ static inline opal_list_item_t *opal_fifo_pop_atomic (opal_fifo_t *fifo)
249246 opal_atomic_wmb ();
250247
251248 item = opal_fifo_head (fifo );
252- if (& fifo -> opal_fifo_ghost == item ) {
249+ if (ghost == item ) {
253250 fifo -> opal_fifo_head .data .counter = 0 ;
254251 return NULL ;
255252 }
@@ -258,9 +255,11 @@ static inline opal_list_item_t *opal_fifo_pop_atomic (opal_fifo_t *fifo)
258255 fifo -> opal_fifo_head .data .item = next ;
259256#endif
260257
261- if (& fifo -> opal_fifo_ghost == next ) {
262- if (!opal_atomic_bool_cmpset_ptr (& fifo -> opal_fifo_tail .data .item , item , & fifo -> opal_fifo_ghost )) {
263- while (& fifo -> opal_fifo_ghost == item -> opal_list_next ) {
258+ if (ghost == next ) {
259+ void * tmp = item ;
260+
261+ if (!opal_atomic_compare_exchange_strong_ptr (& fifo -> opal_fifo_tail .data .item , & tmp , ghost )) {
262+ while (ghost == item -> opal_list_next ) {
264263 opal_atomic_rmb ();
265264 }
266265
0 commit comments