@@ -86,9 +86,12 @@ static inline opal_list_item_t *opal_fifo_push_atomic (opal_fifo_t *fifo,
86
86
opal_list_item_t * item )
87
87
{
88
88
opal_counted_pointer_t tail ;
89
+ const opal_list_item_t * const ghost = & fifo -> opal_fifo_ghost ;
89
90
90
91
item -> opal_list_next = & fifo -> opal_fifo_ghost ;
91
92
93
+ opal_atomic_wmb ();
94
+
92
95
do {
93
96
tail .value = fifo -> opal_fifo_tail .value ;
94
97
@@ -99,7 +102,7 @@ static inline opal_list_item_t *opal_fifo_push_atomic (opal_fifo_t *fifo,
99
102
100
103
opal_atomic_wmb ();
101
104
102
- if (& fifo -> opal_fifo_ghost == tail .data .item ) {
105
+ if (ghost == tail .data .item ) {
103
106
/* update the head */
104
107
opal_counted_pointer_t head = {.value = fifo -> opal_fifo_head .value };
105
108
opal_update_counted_pointer (& fifo -> opal_fifo_head , head , item );
@@ -116,24 +119,23 @@ static inline opal_list_item_t *opal_fifo_push_atomic (opal_fifo_t *fifo,
116
119
*/
117
120
static inline opal_list_item_t * opal_fifo_pop_atomic (opal_fifo_t * fifo )
118
121
{
119
- opal_list_item_t * item , * next ;
122
+ opal_list_item_t * item , * next , * ghost = & fifo -> opal_fifo_ghost ;
120
123
opal_counted_pointer_t head , tail ;
121
124
122
125
do {
123
- head . value = fifo -> opal_fifo_head . value ;
126
+ opal_read_counted_pointer ( & fifo -> opal_fifo_head , & head ) ;
124
127
tail .value = fifo -> opal_fifo_tail .value ;
125
128
opal_atomic_rmb ();
126
129
127
130
item = (opal_list_item_t * ) head .data .item ;
128
131
next = (opal_list_item_t * ) item -> opal_list_next ;
129
132
130
- if (& fifo -> opal_fifo_ghost == tail .data .item && & fifo -> opal_fifo_ghost == item ) {
133
+ if (ghost == tail .data .item && ghost == item ) {
131
134
return NULL ;
132
135
}
133
136
134
137
/* 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 ) {
138
+ if (tail .data .item != item && ghost != tail .data .item && ghost == next ) {
137
139
continue ;
138
140
}
139
141
@@ -146,14 +148,14 @@ static inline opal_list_item_t *opal_fifo_pop_atomic (opal_fifo_t *fifo)
146
148
opal_atomic_wmb ();
147
149
148
150
/* check for tail and head consistency */
149
- if (& fifo -> opal_fifo_ghost == next ) {
151
+ if (ghost == next ) {
150
152
/* 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 )) {
153
+ if (!opal_update_counted_pointer (& fifo -> opal_fifo_tail , tail , ghost )) {
152
154
/* tail was changed by a push operation. wait for the item's next pointer to be se then
153
155
* update the head */
154
156
155
157
/* wait for next pointer to be updated by push */
156
- while (& fifo -> opal_fifo_ghost == item -> opal_list_next ) {
158
+ while (ghost == item -> opal_list_next ) {
157
159
opal_atomic_rmb ();
158
160
}
159
161
@@ -166,7 +168,7 @@ static inline opal_list_item_t *opal_fifo_pop_atomic (opal_fifo_t *fifo)
166
168
head .value = fifo -> opal_fifo_head .value ;
167
169
next = (opal_list_item_t * ) item -> opal_list_next ;
168
170
169
- assert (& fifo -> opal_fifo_ghost == head .data .item );
171
+ assert (ghost == head .data .item );
170
172
171
173
fifo -> opal_fifo_head .data .item = next ;
172
174
opal_atomic_wmb ();
0 commit comments