@@ -188,6 +188,82 @@ struct MultiConsumerTypeTraits
188
188
};
189
189
};
190
190
191
+ struct MultiProducerForSingleConsumerTypeTraits
192
+ {
193
+ template <typename BaseType>
194
+ struct Behavior : BaseType
195
+ {
196
+ private:
197
+ CacheAlignedAndPaddedObject<std::atomic_size_t > end{std::size_t (0 )};
198
+
199
+ public:
200
+ using ElementType = typename BaseType::ElementType;
201
+
202
+ template <typename ... Args>
203
+ bool push (Args &&... args)
204
+ {
205
+ if (BaseType::push_task_count.fetch_sub (1 , std::memory_order_acquire) <= std::int64_t (0 ))
206
+ {
207
+ BaseType::push_task_count.fetch_add (1 , std::memory_order_relaxed);
208
+ return false ;
209
+ }
210
+
211
+ const std::size_t element_index = end.fetch_add (1 , std::memory_order_acquire) & BaseType::COUNT_MASK;
212
+ auto &element = BaseType::elements[element_index];
213
+
214
+ element.value_ptr = new (&element.storage ) ElementType (std::forward<Args>(args)...);
215
+ element.state .store (ElementState::READY_FOR_POP, std::memory_order_release);
216
+ BaseType::pop_task_count.fetch_add (1 , std::memory_order_release);
217
+ return true ;
218
+ }
219
+ };
220
+
221
+ template <typename BaseType, typename = Private::CountInt64CompatibilityCheck<BaseType::COUNT>>
222
+ struct SharedState : BaseType
223
+ {
224
+ protected:
225
+ CacheAlignedAndPaddedObject<std::atomic<std::int64_t >> push_task_count{static_cast <std::int64_t >(BaseType::COUNT)};
226
+ };
227
+ };
228
+
229
+ struct MultiConsumerForSingleProducerTypeTraits
230
+ {
231
+ template <typename BaseType>
232
+ struct Behavior : BaseType
233
+ {
234
+ private:
235
+ CacheAlignedAndPaddedObject<std::atomic_size_t > begin{std::size_t (0 )};
236
+
237
+ public:
238
+ using ElementType = typename BaseType::ElementType;
239
+
240
+ OptionalType<ElementType> pop ()
241
+ {
242
+ if (BaseType::pop_task_count.fetch_sub (1 , std::memory_order_acquire) <= std::int64_t (0 ))
243
+ {
244
+ BaseType::pop_task_count.fetch_add (1 , std::memory_order_relaxed);
245
+ return OptionalType<ElementType>{};
246
+ }
247
+
248
+ const std::size_t element_index = begin.fetch_add (1 , std::memory_order_acquire) & BaseType::COUNT_MASK;
249
+ auto &element = BaseType::elements[element_index];
250
+
251
+ OptionalType<ElementType> result{std::move (*element.value_ptr )};
252
+ element.value_ptr ->~ElementType ();
253
+
254
+ element.state .store (ElementState::READY_FOR_PUSH, std::memory_order_release);
255
+ return result;
256
+ }
257
+ };
258
+
259
+ template <typename BaseType, typename = Private::CountInt64CompatibilityCheck<BaseType::COUNT>>
260
+ struct SharedState : BaseType
261
+ {
262
+ protected:
263
+ CacheAlignedAndPaddedObject<std::atomic<std::int64_t >> pop_task_count{std::int64_t {0 }};
264
+ };
265
+ };
266
+
191
267
struct SingleProducerTypeTraits
192
268
{
193
269
template <typename BaseType>
0 commit comments