diff --git a/include/rexy/mpmc_queue.hpp b/include/rexy/mpmc_queue.hpp index 66b3dd8..60fb11c 100644 --- a/include/rexy/mpmc_queue.hpp +++ b/include/rexy/mpmc_queue.hpp @@ -24,6 +24,7 @@ #include //atomic (duh) #include "rexy.hpp" +#include "utility.hpp" //min #ifdef __cpp_lib_hardware_interference_size #include //hardware_destructive_interference_size @@ -72,7 +73,7 @@ namespace rexy{ alignas(cacheline_size) std::atomic m_turn = {0}; alignas(alignof(value_type)) unsigned char m_data[sizeof(value_type)] = {}; //ensure no false sharing with following data - char cachline_padding[cacheline_size - (sizeof(m_data) + sizeof(m_turn))]; + char cachline_padding[cacheline_size - ((sizeof(m_data) + sizeof(m_turn)) % cacheline_size)]; public: slot() = default; slot(const slot& s); diff --git a/include/rexy/mpmc_queue.tpp b/include/rexy/mpmc_queue.tpp index bdc7230..ec5fa78 100644 --- a/include/rexy/mpmc_queue.tpp +++ b/include/rexy/mpmc_queue.tpp @@ -128,12 +128,13 @@ namespace rexy{ void mpmc_queue::emplace(Args&&... args){ const size_type head = m_head.fetch_add(1, std::memory_order_seq_cst); slot& s = m_slots[head % m_slots.capacity()]; + const size_type rot_count = rotation_cnt(head); //lsb is in-use flag. wait for it to be 0 - while(rotation_cnt(head) << 1 != s.turn().load(std::memory_order_acquire)); + while(rot_count << 1 != s.turn().load(std::memory_order_acquire)); s.construct(std::forward(args)...); //set in-use flag - s.turn().store((rotation_cnt(head) << 1) + 1, std::memory_order_release); + s.turn().store((rot_count << 1) + 1, std::memory_order_release); } template template