@@ -54,71 +54,14 @@ void detail::strategy_based_on_io_scheduler::unlock() noexcept
54
54
55
55
void detail::strategy_based_on_io_scheduler::insert_waiter (wait_operation* waiter) noexcept
56
56
{
57
- while (true )
58
- {
59
- wait_operation* current = m_internal_waiters.load (std::memory_order::acquire);
60
- waiter->m_next .store (current, std::memory_order::release);
61
-
62
- if (!m_internal_waiters.compare_exchange_weak (
63
- current, waiter, std::memory_order::release, std::memory_order::acquire))
64
- {
65
- continue ;
66
- }
67
-
68
- break ;
69
- }
57
+ std::lock_guard<detail::strategy_based_on_io_scheduler> guard{*this };
58
+ m_internal_waiters.insert (waiter->m_awaiting_coroutine );
70
59
}
71
60
72
61
bool detail::strategy_based_on_io_scheduler::extract_waiter (wait_operation* waiter) noexcept
73
62
{
74
63
std::lock_guard<detail::strategy_based_on_io_scheduler> guard{*this };
75
- bool result{};
76
-
77
- while (true )
78
- {
79
- wait_operation* current = m_internal_waiters.load (std::memory_order::acquire);
80
-
81
- if (!current)
82
- {
83
- break ;
84
- }
85
-
86
- wait_operation* next = current->m_next .load (std::memory_order::acquire);
87
-
88
- if (current == waiter)
89
- {
90
- if (!m_internal_waiters.compare_exchange_weak (
91
- current, next, std::memory_order::release, std::memory_order::acquire))
92
- {
93
- continue ;
94
- }
95
- }
96
-
97
- while (next && next != waiter)
98
- {
99
- current = next;
100
- next = current->m_next .load (std::memory_order::acquire);
101
- }
102
-
103
- if (!next)
104
- {
105
- break ;
106
- }
107
-
108
- wait_operation* new_next = waiter->m_next .load (std::memory_order::acquire);
109
-
110
- if (!current->m_next .compare_exchange_strong (
111
- next, new_next, std::memory_order::release, std::memory_order::acquire))
112
- {
113
- continue ;
114
- }
115
-
116
- waiter->m_next .store (nullptr , std::memory_order::release);
117
- result = true ;
118
- break ;
119
- }
120
-
121
- return result;
64
+ return m_internal_waiters.erase (waiter->m_awaiting_coroutine );
122
65
}
123
66
124
67
detail::strategy_based_on_io_scheduler::strategy_based_on_io_scheduler (std::shared_ptr<io_scheduler> io_scheduler)
@@ -133,9 +76,14 @@ void detail::strategy_based_on_io_scheduler::notify_one() noexcept
133
76
134
77
if (auto waiter_guard = extract_one ())
135
78
{
136
- if (auto sched = m_scheduler.lock ())
79
+ auto h = waiter_guard.value ();
80
+
81
+ if (h && !h.done ())
137
82
{
138
- sched->resume (waiter_guard.value ()->m_awaiting_coroutine );
83
+ if (auto sched = m_scheduler.lock ())
84
+ {
85
+ sched->resume (h);
86
+ }
139
87
}
140
88
}
141
89
}
@@ -146,68 +94,37 @@ void detail::strategy_based_on_io_scheduler::notify_all() noexcept
146
94
147
95
if (auto waiter_guard = extract_all ())
148
96
{
97
+ auto values = waiter_guard.values ();
98
+
149
99
if (auto sched = m_scheduler.lock ())
150
100
{
151
- auto * waiter = waiter_guard.value ();
152
- do
101
+ for (const auto & h : values)
153
102
{
154
- auto * next = waiter->m_next .load (std::memory_order::acquire);
155
- sched->resume (waiter->m_awaiting_coroutine );
156
- waiter = next;
157
- } while (waiter);
103
+ if (h && !h.done ())
104
+ {
105
+ sched->resume (h);
106
+ }
107
+ }
158
108
}
159
109
}
160
110
}
161
111
162
112
detail::strategy_based_on_io_scheduler::wait_operation_guard detail::strategy_based_on_io_scheduler::extract_all ()
163
113
{
164
114
wait_operation_guard result{this };
165
-
166
- while (true )
167
- {
168
- auto * current = m_internal_waiters.load (std::memory_order::acquire);
169
- if (!current)
170
- {
171
- break ;
172
- }
173
-
174
- if (!m_internal_waiters.compare_exchange_weak (
175
- current, nullptr , std::memory_order::release, std::memory_order::acquire))
176
- {
177
- continue ;
178
- }
179
-
180
- result.set_value (current);
181
- break ;
182
- }
183
-
115
+ result.set_values (m_internal_waiters);
116
+ m_internal_waiters.clear ();
184
117
return result;
185
118
}
186
119
187
120
detail::strategy_based_on_io_scheduler::wait_operation_guard detail::strategy_based_on_io_scheduler::extract_one ()
188
121
{
189
122
wait_operation_guard result{this };
190
-
191
- while (true )
123
+ if (!m_internal_waiters.empty ())
192
124
{
193
- auto * current = m_internal_waiters.load (std::memory_order::acquire);
194
- if (!current)
195
- {
196
- break ;
197
- }
198
-
199
- auto * next = current->m_next .load (std::memory_order::acquire);
200
- if (!m_internal_waiters.compare_exchange_weak (
201
- current, next, std::memory_order::release, std::memory_order::acquire))
202
- {
203
- continue ;
204
- }
205
-
206
- current->m_next .store (nullptr , std::memory_order::release);
207
- result.set_value (current);
208
- break ;
125
+ result.set_value (*m_internal_waiters.begin ());
126
+ m_internal_waiters.erase (m_internal_waiters.begin ());
209
127
}
210
-
211
128
return result;
212
129
}
213
130
@@ -234,31 +151,45 @@ void detail::strategy_based_on_io_scheduler::wait_operation::await_resume() noex
234
151
}
235
152
236
153
detail::strategy_based_on_io_scheduler::wait_operation_guard::wait_operation_guard (
237
- detail::strategy_based_on_io_scheduler* cv ) noexcept
238
- : m_cv(cv )
154
+ detail::strategy_based_on_io_scheduler* strategy ) noexcept
155
+ : m_strategy(strategy )
239
156
{
240
- m_cv ->lock ();
157
+ m_strategy ->lock ();
241
158
}
242
159
243
160
detail::strategy_based_on_io_scheduler::wait_operation_guard::~wait_operation_guard ()
244
161
{
245
- m_cv ->unlock ();
162
+ m_strategy ->unlock ();
246
163
}
247
164
248
165
detail::strategy_based_on_io_scheduler::wait_operation_guard::operator bool () const noexcept
249
166
{
250
- return m_value;
167
+ return !m_values.empty ();
168
+ }
169
+
170
+ void detail::strategy_based_on_io_scheduler::wait_operation_guard::set_value (std::coroutine_handle<> value) noexcept
171
+ {
172
+ m_values = {value};
173
+ }
174
+
175
+ std::coroutine_handle<> detail::strategy_based_on_io_scheduler::wait_operation_guard::value () const noexcept
176
+ {
177
+ if (m_values.empty ())
178
+ return nullptr ;
179
+
180
+ return *m_values.begin ();
251
181
}
252
182
253
- void detail::strategy_based_on_io_scheduler::wait_operation_guard::set_value (wait_operation* value) noexcept
183
+ void detail::strategy_based_on_io_scheduler::wait_operation_guard::set_values (
184
+ std::unordered_set<std::coroutine_handle<>> values) noexcept
254
185
{
255
- m_value = value ;
186
+ m_values = values ;
256
187
}
257
188
258
- detail::strategy_based_on_io_scheduler::wait_operation*
259
- detail::strategy_based_on_io_scheduler::wait_operation_guard::value () const noexcept
189
+ std::unordered_set<std::coroutine_handle<>>
190
+ detail::strategy_based_on_io_scheduler::wait_operation_guard::values () const noexcept
260
191
{
261
- return m_value ;
192
+ return m_values ;
262
193
}
263
194
264
195
#endif
0 commit comments