From 868f30e606572c4b72579b3b89c58cb9d27dfe40 Mon Sep 17 00:00:00 2001 From: Niellune Date: Mon, 23 Mar 2026 18:48:39 +0200 Subject: [PATCH] Atomic queue explicit atomic operations --- src/struct/atomic_queue.h | 45 ++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/src/struct/atomic_queue.h b/src/struct/atomic_queue.h index 2b42b8b..b70f7ca 100644 --- a/src/struct/atomic_queue.h +++ b/src/struct/atomic_queue.h @@ -1,6 +1,7 @@ #ifndef SRC_STRUCT_ATOMIC_QUEUE #define SRC_STRUCT_ATOMIC_QUEUE +#include #include #include #include @@ -13,7 +14,7 @@ template class AtomicQueue { public: - AtomicQueue(uint16_t size) + AtomicQueue(size_t size) : _size(size), _data(new unique_ptr[size]), _first(0), _last(0), _count(0) { } @@ -25,19 +26,19 @@ public: bool pushDiscard(unique_ptr obj) { - if (_count == _size) + if (_count.load(std::memory_order_acquire) == _size) return false; _first = (_first + 1) % _size; _data[_first] = std::move(obj); - ++_count; + _count.fetch_add(1, std::memory_order_release); _lock.notify_one(); return true; } bool pushReplace(unique_ptr obj) { - if (_count == _size) + if (_count.load(std::memory_order_acquire) == _size) { _data[_first] = std::move(obj); return false; @@ -45,49 +46,49 @@ public: _first = (_first + 1) % _size; _data[_first] = std::move(obj); - ++_count; + _count.fetch_add(1, std::memory_order_release); _lock.notify_one(); return true; } const T *peek() { - if (_count == 0) + if (_count.load(std::memory_order_acquire) == 0) return nullptr; return _data[(_last + 1) % _size].get(); } unique_ptr pop() { - if (_count == 0) + if (_count.load(std::memory_order_acquire) == 0) return nullptr; _last = (_last + 1) % _size; auto item = std::move(_data[_last]); - --_count; + _count.fetch_sub(1, std::memory_order_release); return item; } - bool has(uint8_t count) + bool has(size_t count) { - return _count >= count; + return _count.load(std::memory_order_acquire) >= count; } - bool wait(atomic &waitFlag, uint8_t count = 0) + bool wait(atomic &waitFlag, size_t count = 0) { unique_lock lock(_mtx); _lock.wait(lock, [&] - { return _count > count || !waitFlag.load(); }); - return waitFlag.load(); + { return _count.load(std::memory_order_acquire) > count || !waitFlag.load(std::memory_order_acquire); }); + return waitFlag.load(std::memory_order_acquire); } - bool waitFor(atomic &waitFlag, uint32_t timeoutMs, uint8_t count = 0) + bool waitFor(atomic &waitFlag, uint32_t timeoutMs, size_t count = 0) { unique_lock lock(_mtx); _lock.wait_for(lock, std::chrono::milliseconds(timeoutMs), [&] - { return _count > count || !waitFlag.load(); }); - return waitFlag.load(); + { return _count.load(std::memory_order_acquire) > count || !waitFlag.load(std::memory_order_acquire); }); + return waitFlag.load(std::memory_order_acquire); } void clear() @@ -95,7 +96,7 @@ public: _data = std::make_unique[]>(_size); _first = 0; _last = 0; - _count = 0; + _count.store(0, std::memory_order_release); } void notify() @@ -103,14 +104,14 @@ public: _lock.notify_all(); } - uint16_t count() { return _count; } + size_t count() { return _count.load(std::memory_order_acquire); } private: - uint16_t _size; + size_t _size; unique_ptr[]> _data; - uint16_t _first; - uint16_t _last; - atomic _count; + size_t _first; + size_t _last; + atomic _count; mutex _mtx; condition_variable _lock; };