From 91ca23a23d749a36ebf6d5fb0ed0392edff62dbd Mon Sep 17 00:00:00 2001 From: IYP-Programer-Yeah Date: Sun, 31 May 2020 00:17:27 +0430 Subject: [PATCH] Make SCMP and MCSP FIFO and more performant. --- .../details/ring-buffer-type-constructor.inl | 76 +++++++++++++++++++ ...i-producer-single-consumer-ring-buffer.inl | 2 +- ...le-producer-multi-consumer-ring-buffer.inl | 2 +- 3 files changed, 78 insertions(+), 2 deletions(-) diff --git a/WaitFreeRingBufferUtilities/Include/details/ring-buffer-type-constructor.inl b/WaitFreeRingBufferUtilities/Include/details/ring-buffer-type-constructor.inl index d736d57..a720039 100644 --- a/WaitFreeRingBufferUtilities/Include/details/ring-buffer-type-constructor.inl +++ b/WaitFreeRingBufferUtilities/Include/details/ring-buffer-type-constructor.inl @@ -188,6 +188,82 @@ struct MultiConsumerTypeTraits }; }; +struct MultiProducerForSingleConsumerTypeTraits +{ + template + struct Behavior : BaseType + { + private: + CacheAlignedAndPaddedObject end{std::size_t(0)}; + + public: + using ElementType = typename BaseType::ElementType; + + template + bool push(Args &&... args) + { + if (BaseType::push_task_count.fetch_sub(1, std::memory_order_acquire) <= std::int64_t(0)) + { + BaseType::push_task_count.fetch_add(1, std::memory_order_relaxed); + return false; + } + + const std::size_t element_index = end.fetch_add(1, std::memory_order_acquire) & BaseType::COUNT_MASK; + auto &element = BaseType::elements[element_index]; + + element.value_ptr = new (&element.storage) ElementType(std::forward(args)...); + element.state.store(ElementState::READY_FOR_POP, std::memory_order_release); + BaseType::pop_task_count.fetch_add(1, std::memory_order_release); + return true; + } + }; + + template > + struct SharedState : BaseType + { + protected: + CacheAlignedAndPaddedObject> push_task_count{static_cast(BaseType::COUNT)}; + }; +}; + +struct MultiConsumerForSingleProducerTypeTraits +{ + template + struct Behavior : BaseType + { + private: + CacheAlignedAndPaddedObject begin{std::size_t(0)}; + + public: + using ElementType = typename BaseType::ElementType; + + OptionalType pop() + { + if (BaseType::pop_task_count.fetch_sub(1, std::memory_order_acquire) <= std::int64_t(0)) + { + BaseType::pop_task_count.fetch_add(1, std::memory_order_relaxed); + return OptionalType{}; + } + + const std::size_t element_index = begin.fetch_add(1, std::memory_order_acquire) & BaseType::COUNT_MASK; + auto &element = BaseType::elements[element_index]; + + OptionalType result{std::move(*element.value_ptr)}; + element.value_ptr->~ElementType(); + + element.state.store(ElementState::READY_FOR_PUSH, std::memory_order_release); + return result; + } + }; + + template > + struct SharedState : BaseType + { + protected: + CacheAlignedAndPaddedObject> pop_task_count{std::int64_t{0}}; + }; +}; + struct SingleProducerTypeTraits { template diff --git a/WaitFreeRingBufferUtilities/Include/multi-producer-single-consumer-ring-buffer.inl b/WaitFreeRingBufferUtilities/Include/multi-producer-single-consumer-ring-buffer.inl index 0f0bb34..15d8e2d 100644 --- a/WaitFreeRingBufferUtilities/Include/multi-producer-single-consumer-ring-buffer.inl +++ b/WaitFreeRingBufferUtilities/Include/multi-producer-single-consumer-ring-buffer.inl @@ -13,7 +13,7 @@ namespace WaitFreeRingBufferUtilities template struct RingBuffer : Details::RingBufferTypeConstructor : Details::RingBufferTypeConstructor { diff --git a/WaitFreeRingBufferUtilities/Include/single-producer-multi-consumer-ring-buffer.inl b/WaitFreeRingBufferUtilities/Include/single-producer-multi-consumer-ring-buffer.inl index f70fd46..01192e5 100644 --- a/WaitFreeRingBufferUtilities/Include/single-producer-multi-consumer-ring-buffer.inl +++ b/WaitFreeRingBufferUtilities/Include/single-producer-multi-consumer-ring-buffer.inl @@ -14,7 +14,7 @@ template struct RingBuffer : Details::RingBufferTypeConstructor { };