Skip to content

Commit c48a91d

Browse files
Make SCMP and MCSP FIFO and more performant.
1 parent 5b462e1 commit c48a91d

File tree

3 files changed

+78
-2
lines changed

3 files changed

+78
-2
lines changed

WaitFreeRingBufferUtilities/Include/details/ring-buffer-type-constructor.inl

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,82 @@ struct MultiConsumerTypeTraits
188188
};
189189
};
190190

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+
191267
struct SingleProducerTypeTraits
192268
{
193269
template <typename BaseType>

WaitFreeRingBufferUtilities/Include/multi-producer-single-consumer-ring-buffer.inl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ namespace WaitFreeRingBufferUtilities
1313
template <typename T, std::size_t Count>
1414
struct RingBuffer<T,
1515
AccessRequirements::SINGLE_CONSUMER | AccessRequirements::MULTI_PRODUCER,
16-
Count> : Details::RingBufferTypeConstructor<Details::MultiProducerTypeTraits,
16+
Count> : Details::RingBufferTypeConstructor<Details::MultiProducerForSingleConsumerTypeTraits,
1717
Details::SingleConsumerTypeTraits,
1818
T, Count>
1919
{

WaitFreeRingBufferUtilities/Include/single-producer-multi-consumer-ring-buffer.inl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ template <typename T, std::size_t Count>
1414
struct RingBuffer<T,
1515
AccessRequirements::MULTI_CONSUMER | AccessRequirements::SINGLE_PRODUCER,
1616
Count> : Details::RingBufferTypeConstructor<Details::SingleProducerTypeTraits,
17-
Details::MultiConsumerTypeTraits,
17+
Details::MultiConsumerForSingleProducerTypeTraits,
1818
T, Count>
1919
{
2020
};

0 commit comments

Comments
 (0)