8
8
#include < functional>
9
9
#include < optional>
10
10
11
- #define LOG (...) std::cout << __VA_ARGS__ " \n "
12
-
13
11
struct thread_group {
14
12
private:
15
13
std::vector<std::thread> members;
@@ -54,26 +52,6 @@ struct concurrent_bounded_queue {
54
52
items_produced.release ();
55
53
}
56
54
57
- // Attempt to dequeue one entry.
58
- std::optional<T> try_dequeue ()
59
- {
60
- std::optional<T> tmp;
61
- if (!items_produced.try_acquire ())
62
- return tmp;
63
- // This sleep is a stand-in for a log statement in the actual code. The bug
64
- // reproduces without the delay after acquiring and before locking, but it
65
- // reproduces much less frequently.
66
- std::this_thread::sleep_for (std::chrono::nanoseconds (500 ));
67
- {
68
- std::scoped_lock l (items_mtx);
69
- assert (!items.empty ());
70
- tmp = std::move (items.front ());
71
- items.pop ();
72
- }
73
- remaining_space.release ();
74
- return tmp;
75
- }
76
-
77
55
// Attempt to dequeue one entry with a timeout.
78
56
template <typename Rep, typename Period>
79
57
std::optional<T> try_dequeue_for (
@@ -113,7 +91,6 @@ int main()
113
91
114
92
constexpr std::size_t num_threads = 8 ;
115
93
116
- std::latch l (num_threads + 1 );
117
94
thread_group tg (num_threads,
118
95
[&]
119
96
{
@@ -124,25 +101,18 @@ int main()
124
101
(*f)();
125
102
}
126
103
}
127
- // Clear out the queue.
128
- while (true ) {
129
- auto f = tasks.try_dequeue ();
130
- if (f) {
131
- assert (*f);
132
- (*f)();
133
- } else
134
- // We weren't able to dequeue anything; the queue's empty.
135
- break ;
136
- }
137
- l.arrive_and_wait ();
138
104
}
139
105
);
140
106
141
107
for (std::size_t i = 0 ; i < num_enqueues_per_run; ++i)
142
108
tasks.enqueue ([&] { ++count; });
143
109
144
- stop_requested.store (true , std::memory_order_relaxed);
110
+ std::latch l (num_threads + 1 );
111
+ for (std::size_t i = 0 ; i < num_threads; ++i)
112
+ tasks.enqueue ([&] { l.arrive_and_wait (); });
145
113
l.arrive_and_wait ();
114
+
115
+ stop_requested.store (true , std::memory_order_relaxed);
146
116
}
147
117
148
118
assert (num_runs * num_enqueues_per_run == count);
0 commit comments