12
12
* All rights reserved.
13
13
* Copyright (c) 2007 Voltaire All rights reserved.
14
14
* 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
16
16
* reseved.
17
17
* $COPYRIGHT$
18
18
*
@@ -85,14 +85,12 @@ static inline bool opal_fifo_is_empty( opal_fifo_t* fifo )
85
85
static inline opal_list_item_t * opal_fifo_push_atomic (opal_fifo_t * fifo ,
86
86
opal_list_item_t * item )
87
87
{
88
- opal_counted_pointer_t tail ;
88
+ opal_counted_pointer_t tail = {. value = fifo -> opal_fifo_tail . value } ;
89
89
90
90
item -> opal_list_next = & fifo -> opal_fifo_ghost ;
91
91
92
92
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 )) {
96
94
break ;
97
95
}
98
96
} while (1 );
@@ -102,7 +100,7 @@ static inline opal_list_item_t *opal_fifo_push_atomic (opal_fifo_t *fifo,
102
100
if (& fifo -> opal_fifo_ghost == tail .data .item ) {
103
101
/* update the head */
104
102
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 );
106
104
} else {
107
105
/* update previous item */
108
106
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,
116
114
*/
117
115
static inline opal_list_item_t * opal_fifo_pop_atomic (opal_fifo_t * fifo )
118
116
{
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 ;
121
119
122
120
do {
123
- head .value = fifo -> opal_fifo_head .value ;
124
121
tail .value = fifo -> opal_fifo_tail .value ;
125
122
opal_atomic_rmb ();
126
123
127
124
item = (opal_list_item_t * ) head .data .item ;
128
125
next = (opal_list_item_t * ) item -> opal_list_next ;
129
126
130
- if (& fifo -> opal_fifo_ghost == tail .data .item && & fifo -> opal_fifo_ghost == item ) {
127
+ if (ghost == tail .data .item && ghost == item ) {
131
128
return NULL ;
132
129
}
133
130
134
131
/* 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 ;
137
134
continue ;
138
135
}
139
136
140
137
/* 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 )) {
142
139
break ;
143
140
}
144
141
} while (1 );
145
142
146
143
opal_atomic_wmb ();
147
144
148
145
/* check for tail and head consistency */
149
- if (& fifo -> opal_fifo_ghost == next ) {
146
+ if (ghost == next ) {
150
147
/* 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 )) {
152
149
/* tail was changed by a push operation. wait for the item's next pointer to be se then
153
150
* update the head */
154
151
155
152
/* 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 ) {
157
154
opal_atomic_rmb ();
158
155
}
159
156
@@ -166,7 +163,7 @@ static inline opal_list_item_t *opal_fifo_pop_atomic (opal_fifo_t *fifo)
166
163
head .value = fifo -> opal_fifo_head .value ;
167
164
next = (opal_list_item_t * ) item -> opal_list_next ;
168
165
169
- assert (& fifo -> opal_fifo_ghost == head .data .item );
166
+ assert (ghost == head .data .item );
170
167
171
168
fifo -> opal_fifo_head .data .item = next ;
172
169
opal_atomic_wmb ();
@@ -215,14 +212,14 @@ static inline opal_list_item_t *opal_fifo_push_atomic (opal_fifo_t *fifo,
215
212
*/
216
213
static inline opal_list_item_t * opal_fifo_pop_atomic (opal_fifo_t * fifo )
217
214
{
218
- opal_list_item_t * item , * next ;
215
+ opal_list_item_t * item , * next , * ghost = & fifo -> opal_fifo_ghost ;
219
216
220
217
#if OPAL_HAVE_ATOMIC_LLSC_PTR
221
218
/* use load-linked store-conditional to avoid ABA issues */
222
219
do {
223
220
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 ) {
226
223
return NULL ;
227
224
}
228
225
@@ -239,7 +236,7 @@ static inline opal_list_item_t *opal_fifo_pop_atomic (opal_fifo_t *fifo)
239
236
#else
240
237
/* protect against ABA issues by "locking" the head */
241
238
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 )) {
243
240
break ;
244
241
}
245
242
@@ -249,7 +246,7 @@ static inline opal_list_item_t *opal_fifo_pop_atomic (opal_fifo_t *fifo)
249
246
opal_atomic_wmb ();
250
247
251
248
item = opal_fifo_head (fifo );
252
- if (& fifo -> opal_fifo_ghost == item ) {
249
+ if (ghost == item ) {
253
250
fifo -> opal_fifo_head .data .counter = 0 ;
254
251
return NULL ;
255
252
}
@@ -258,9 +255,11 @@ static inline opal_list_item_t *opal_fifo_pop_atomic (opal_fifo_t *fifo)
258
255
fifo -> opal_fifo_head .data .item = next ;
259
256
#endif
260
257
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 ) {
264
263
opal_atomic_rmb ();
265
264
}
266
265
0 commit comments