diff --git a/src/external/atomic_queue/atomic_queue.h b/src/external/atomic_queue/atomic_queue.h index f679d32c..1319f6f9 100644 --- a/src/external/atomic_queue/atomic_queue.h +++ b/src/external/atomic_queue/atomic_queue.h @@ -55,15 +55,13 @@ struct GetIndexShuffleBits { // the element within the cache line) with the next N bits (which are the index of the cache line) // of the element index. template -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); } template constexpr unsigned remap_index(unsigned index) noexcept { - return remap_index_with_mix( - index, (index ^ (index >> BITS)) & ((1u << BITS) - 1)); + return remap_index_with_mix(index, (index ^ (index >> BITS)) & ((1u << BITS) - 1)); } template<> @@ -133,7 +131,7 @@ protected: // The special member functions are not thread-safe. - AtomicQueueCommon() = default; + AtomicQueueCommon() noexcept = default; AtomicQueueCommon(AtomicQueueCommon const& b) noexcept : head_(b.head_.load(X)) @@ -213,7 +211,7 @@ protected: else { for(;;) { 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)}; state.store(EMPTY, R); return element; @@ -238,7 +236,7 @@ protected: else { for(;;) { 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(element); state.store(STORED, R); return; @@ -318,11 +316,16 @@ public: } bool was_empty() const noexcept { - return static_cast(head_.load(X) - tail_.load(X)) <= 0; + return !was_size(); } bool was_full() const noexcept { - return static_cast(head_.load(X) - tail_.load(X)) >= static_cast(static_cast(*this).size_); + return was_size() >= static_cast(static_cast(*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(head_.load(X) - tail_.load(X)), 0); } unsigned capacity() const noexcept { @@ -400,7 +403,7 @@ class AtomicQueue2 : public AtomicQueueCommon(expr), 1) #define ATOMIC_QUEUE_UNLIKELY(expr) __builtin_expect(static_cast(expr), 0) +#define ATOMIC_QUEUE_NOINLINE __attribute__((noinline)) #else -#define ATOMIC_QUEUE_LIKELY(expr) expr -#define ATOMIC_QUEUE_UNLIKELY(expr) expr +#define ATOMIC_QUEUE_LIKELY(expr) (expr) +#define ATOMIC_QUEUE_UNLIKELY(expr) (expr) +#define ATOMIC_QUEUE_NOINLINE #endif //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/sfizz/FilePool.h b/src/sfizz/FilePool.h index 41068598..7f8be842 100644 --- a/src/sfizz/FilePool.h +++ b/src/sfizz/FilePool.h @@ -342,13 +342,9 @@ private: struct QueuedFileData { using TimePoint = std::chrono::time_point; - QueuedFileData() = default; - QueuedFileData(std::weak_ptr id, FileData* data, TimePoint queuedTime) + QueuedFileData() noexcept {} + QueuedFileData(std::weak_ptr id, FileData* data, TimePoint queuedTime) noexcept : id(id), data(data), queuedTime(queuedTime) {} - QueuedFileData(const QueuedFileData&) = default; - QueuedFileData& operator=(const QueuedFileData&) = default; - QueuedFileData(QueuedFileData&&) = default; - QueuedFileData& operator=(QueuedFileData&&) = default; std::weak_ptr id; FileData* data { nullptr }; TimePoint queuedTime {};