@@ -69,30 +69,26 @@ class guard_ptr
69
69
{
70
70
using namespace std ::chrono_literals;
71
71
72
- node<T>* current = ref.load (std::memory_order::relaxed);
73
72
do
74
73
{
75
- node<T>* result = current;
76
- m_node_ptr = current;
77
- if (m_node_ptr)
74
+ m_node_ptr = ref.load (std::memory_order::acquire);
75
+ if (!m_node_ptr)
78
76
{
79
- m_node_ptr->ref_count .fetch_add (1 , std::memory_order::acq_rel);
80
- if (m_node_ptr->is_removed .load (std::memory_order::acquire))
81
- {
82
- decrement ();
83
- m_is_removed = true ;
84
- return ;
85
- }
77
+ return ;
86
78
}
87
- current = ref.load (std::memory_order::acquire);
88
- if (result == current)
89
- break ;
90
-
91
- if (m_node_ptr)
79
+ if (m_node_ptr->is_removed .load (std::memory_order::acquire))
92
80
{
93
- decrement ();
81
+ m_is_removed = true ;
82
+ m_node_ptr = nullptr ;
83
+ return ;
84
+ }
85
+ node<T>* current = ref.load (std::memory_order::acquire);
86
+ if (m_node_ptr == current)
87
+ {
88
+ break ;
94
89
}
95
90
} while (true );
91
+ m_node_ptr->ref_count .fetch_add (1 , std::memory_order::acq_rel);
96
92
}
97
93
98
94
void remove ()
@@ -222,33 +218,33 @@ class lockfree_queue
222
218
using namespace std ::chrono_literals;
223
219
224
220
auto new_node = m_alloc.allocate (value);
221
+ assert (new_node->next .load () == nullptr );
225
222
while (true )
226
223
{
227
224
guard_type tail_guard (m_tail, [this ](node_type* n) { dispose_node (n); });
228
225
if (tail_guard.is_removed ())
229
226
{
230
227
continue ;
231
228
}
232
- auto tail_node = tail_guard.value ();
233
- guard_type next_guard (tail_node->next , [this ](node_type* n) { dispose_node (n); });
234
- if (next_guard.is_removed ())
235
- {
236
- continue ;
237
- }
238
- auto next_node = next_guard.value ();
229
+ auto tail_node = tail_guard.value ();
230
+ assert (tail_node != new_node);
231
+ auto next_node = tail_node->next .load (std::memory_order::acquire);
239
232
240
233
if (next_node != nullptr )
241
234
{
235
+ assert (tail_node != next_node);
236
+
242
237
// Tail is misplaced, advance it
243
238
m_tail.compare_exchange_weak (
244
239
tail_node, next_node, std::memory_order::release, std::memory_order::relaxed);
245
240
continue ;
246
241
}
247
242
248
- node_type* expected{} ;
243
+ node_type* expected = nullptr ;
249
244
if (tail_node->next .compare_exchange_strong (
250
245
expected, new_node, std::memory_order::release, std::memory_order::relaxed))
251
246
{
247
+ assert (tail_node != new_node);
252
248
m_tail.compare_exchange_strong (
253
249
tail_node, new_node, std::memory_order::release, std::memory_order::relaxed);
254
250
return ;
@@ -291,12 +287,16 @@ class lockfree_queue
291
287
292
288
if (head_node == tail_node)
293
289
{
290
+ assert (tail_node != next_node);
291
+
294
292
// It is needed to help push()
295
293
m_tail.compare_exchange_strong (
296
294
tail_node, next_node, std::memory_order::release, std::memory_order::relaxed);
297
295
continue ;
298
296
}
299
297
298
+ assert (head_node != next_node);
299
+
300
300
if (m_head.compare_exchange_strong (
301
301
head_node, next_node, std::memory_order::acquire, std::memory_order::relaxed))
302
302
{
0 commit comments