Fix bug in mpmc_queue causing objects larger than cacheline to fail during compilation
This commit is contained in:
parent
c5776e8d2f
commit
a17886b706
@ -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);
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user