Fix bug in mpmc_queue causing objects larger than cacheline to fail during compilation

This commit is contained in:
rexy712 2021-06-18 21:46:55 -07:00
parent c5776e8d2f
commit a17886b706
2 changed files with 5 additions and 3 deletions

View File

@ -24,6 +24,7 @@
#include <atomic> //atomic (duh) #include <atomic> //atomic (duh)
#include "rexy.hpp" #include "rexy.hpp"
#include "utility.hpp" //min
#ifdef __cpp_lib_hardware_interference_size #ifdef __cpp_lib_hardware_interference_size
#include <new> //hardware_destructive_interference_size #include <new> //hardware_destructive_interference_size
@ -72,7 +73,7 @@ namespace rexy{
alignas(cacheline_size) std::atomic<size_type> m_turn = {0}; alignas(cacheline_size) std::atomic<size_type> m_turn = {0};
alignas(alignof(value_type)) unsigned char m_data[sizeof(value_type)] = {}; alignas(alignof(value_type)) unsigned char m_data[sizeof(value_type)] = {};
//ensure no false sharing with following data //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: public:
slot() = default; slot() = default;
slot(const slot& s); slot(const slot& s);

View File

@ -128,12 +128,13 @@ namespace rexy{
void mpmc_queue<T>::emplace(Args&&... args){ void mpmc_queue<T>::emplace(Args&&... args){
const size_type head = m_head.fetch_add(1, std::memory_order_seq_cst); const size_type head = m_head.fetch_add(1, std::memory_order_seq_cst);
slot& s = m_slots[head % m_slots.capacity()]; 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 //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>(args)...); s.construct(std::forward<Args>(args)...);
//set in-use flag //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<class T> template<class T>
template<class... Args> template<class... Args>