Update atomic_queue for a bugfix
This commit is contained in:
parent
078615c761
commit
0c8fb5fbc4
2 changed files with 17 additions and 13 deletions
23
src/external/atomic_queue/atomic_queue.h
vendored
23
src/external/atomic_queue/atomic_queue.h
vendored
|
|
@ -55,15 +55,13 @@ struct GetIndexShuffleBits<false, array_size, elements_per_cache_line> {
|
||||||
// the element within the cache line) with the next N bits (which are the index of the cache line)
|
// the element within the cache line) with the next N bits (which are the index of the cache line)
|
||||||
// of the element index.
|
// of the element index.
|
||||||
template<int BITS>
|
template<int BITS>
|
||||||
constexpr unsigned remap_index_with_mix(unsigned index, unsigned mix)
|
constexpr unsigned remap_index_with_mix(unsigned index, unsigned mix) {
|
||||||
{
|
|
||||||
return index ^ mix ^ (mix << BITS);
|
return index ^ mix ^ (mix << BITS);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int BITS>
|
template<int BITS>
|
||||||
constexpr unsigned remap_index(unsigned index) noexcept {
|
constexpr unsigned remap_index(unsigned index) noexcept {
|
||||||
return remap_index_with_mix<BITS>(
|
return remap_index_with_mix<BITS>(index, (index ^ (index >> BITS)) & ((1u << BITS) - 1));
|
||||||
index, (index ^ (index >> BITS)) & ((1u << BITS) - 1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
|
@ -133,7 +131,7 @@ protected:
|
||||||
|
|
||||||
// The special member functions are not thread-safe.
|
// The special member functions are not thread-safe.
|
||||||
|
|
||||||
AtomicQueueCommon() = default;
|
AtomicQueueCommon() noexcept = default;
|
||||||
|
|
||||||
AtomicQueueCommon(AtomicQueueCommon const& b) noexcept
|
AtomicQueueCommon(AtomicQueueCommon const& b) noexcept
|
||||||
: head_(b.head_.load(X))
|
: head_(b.head_.load(X))
|
||||||
|
|
@ -213,7 +211,7 @@ protected:
|
||||||
else {
|
else {
|
||||||
for(;;) {
|
for(;;) {
|
||||||
unsigned char expected = STORED;
|
unsigned char expected = STORED;
|
||||||
if(ATOMIC_QUEUE_LIKELY(state.compare_exchange_strong(expected, LOADING, X, X))) {
|
if(ATOMIC_QUEUE_LIKELY(state.compare_exchange_strong(expected, LOADING, A, X))) {
|
||||||
T element{std::move(q_element)};
|
T element{std::move(q_element)};
|
||||||
state.store(EMPTY, R);
|
state.store(EMPTY, R);
|
||||||
return element;
|
return element;
|
||||||
|
|
@ -238,7 +236,7 @@ protected:
|
||||||
else {
|
else {
|
||||||
for(;;) {
|
for(;;) {
|
||||||
unsigned char expected = EMPTY;
|
unsigned char expected = EMPTY;
|
||||||
if(ATOMIC_QUEUE_LIKELY(state.compare_exchange_strong(expected, STORING, X, X))) {
|
if(ATOMIC_QUEUE_LIKELY(state.compare_exchange_strong(expected, STORING, A, X))) {
|
||||||
q_element = std::forward<U>(element);
|
q_element = std::forward<U>(element);
|
||||||
state.store(STORED, R);
|
state.store(STORED, R);
|
||||||
return;
|
return;
|
||||||
|
|
@ -318,11 +316,16 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
bool was_empty() const noexcept {
|
bool was_empty() const noexcept {
|
||||||
return static_cast<int>(head_.load(X) - tail_.load(X)) <= 0;
|
return !was_size();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool was_full() const noexcept {
|
bool was_full() const noexcept {
|
||||||
return static_cast<int>(head_.load(X) - tail_.load(X)) >= static_cast<int>(static_cast<Derived const&>(*this).size_);
|
return was_size() >= static_cast<int>(static_cast<Derived const&>(*this).size_);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned was_size() const noexcept {
|
||||||
|
// tail_ can be greater than head_ because of consumers doing pop, rather that try_pop, when the queue is empty.
|
||||||
|
return std::max(static_cast<int>(head_.load(X) - tail_.load(X)), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned capacity() const noexcept {
|
unsigned capacity() const noexcept {
|
||||||
|
|
@ -400,7 +403,7 @@ class AtomicQueue2 : public AtomicQueueCommon<AtomicQueue2<T, SIZE, MINIMIZE_CON
|
||||||
public:
|
public:
|
||||||
using value_type = T;
|
using value_type = T;
|
||||||
|
|
||||||
AtomicQueue2() = default;
|
AtomicQueue2() noexcept = default;
|
||||||
AtomicQueue2(AtomicQueue2 const&) = delete;
|
AtomicQueue2(AtomicQueue2 const&) = delete;
|
||||||
AtomicQueue2& operator=(AtomicQueue2 const&) = delete;
|
AtomicQueue2& operator=(AtomicQueue2 const&) = delete;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
7
src/external/atomic_queue/defs.h
vendored
7
src/external/atomic_queue/defs.h
vendored
|
|
@ -16,7 +16,6 @@ static inline void spin_loop_pause() noexcept {
|
||||||
}
|
}
|
||||||
} // namespace atomic_queue
|
} // namespace atomic_queue
|
||||||
#elif defined(__arm__) || defined(__aarch64__)
|
#elif defined(__arm__) || defined(__aarch64__)
|
||||||
// TODO: These need to be verified as I do not have access to ARM platform.
|
|
||||||
namespace atomic_queue {
|
namespace atomic_queue {
|
||||||
constexpr int CACHE_LINE_SIZE = 64;
|
constexpr int CACHE_LINE_SIZE = 64;
|
||||||
static inline void spin_loop_pause() noexcept {
|
static inline void spin_loop_pause() noexcept {
|
||||||
|
|
@ -48,9 +47,11 @@ namespace atomic_queue {
|
||||||
#if defined(__GNUC__) || defined(__clang__)
|
#if defined(__GNUC__) || defined(__clang__)
|
||||||
#define ATOMIC_QUEUE_LIKELY(expr) __builtin_expect(static_cast<bool>(expr), 1)
|
#define ATOMIC_QUEUE_LIKELY(expr) __builtin_expect(static_cast<bool>(expr), 1)
|
||||||
#define ATOMIC_QUEUE_UNLIKELY(expr) __builtin_expect(static_cast<bool>(expr), 0)
|
#define ATOMIC_QUEUE_UNLIKELY(expr) __builtin_expect(static_cast<bool>(expr), 0)
|
||||||
|
#define ATOMIC_QUEUE_NOINLINE __attribute__((noinline))
|
||||||
#else
|
#else
|
||||||
#define ATOMIC_QUEUE_LIKELY(expr) expr
|
#define ATOMIC_QUEUE_LIKELY(expr) (expr)
|
||||||
#define ATOMIC_QUEUE_UNLIKELY(expr) expr
|
#define ATOMIC_QUEUE_UNLIKELY(expr) (expr)
|
||||||
|
#define ATOMIC_QUEUE_NOINLINE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue