From 3bc78e577f2a474a1d09b720e45b6e8f170a6711 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Tue, 12 Feb 2019 22:03:48 -0500 Subject: [PATCH 1/2] threadsafe_queue: Remove NeedSize template parameter The necessity of this parameter is dubious at best, and in 2019 probably offers completely negligible savings as opposed to just leaving this enabled. This removes it and simplifies the overall interface. --- src/common/threadsafe_queue.h | 22 ++++++++++------------ src/core/core_timing.h | 2 +- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/src/common/threadsafe_queue.h b/src/common/threadsafe_queue.h index 68955d66d0..c5fb7a27c6 100644 --- a/src/common/threadsafe_queue.h +++ b/src/common/threadsafe_queue.h @@ -15,10 +15,10 @@ #include "common/common_types.h" namespace Common { -template +template class SPSCQueue { public: - SPSCQueue() : size(0) { + SPSCQueue() { write_ptr = read_ptr = new ElementPtr(); } ~SPSCQueue() { @@ -27,12 +27,11 @@ public: } u32 Size() const { - static_assert(NeedSize, "using Size() on FifoQueue without NeedSize"); return size.load(); } bool Empty() const { - return !read_ptr->next.load(); + return Size() == 0; } T& Front() const { @@ -48,14 +47,14 @@ public: ElementPtr* new_ptr = new ElementPtr(); write_ptr->next.store(new_ptr, std::memory_order_release); write_ptr = new_ptr; - if (NeedSize) - size++; cv.notify_one(); + + ++size; } void Pop() { - if (NeedSize) - size--; + --size; + ElementPtr* tmpptr = read_ptr; // advance the read pointer read_ptr = tmpptr->next.load(); @@ -68,8 +67,7 @@ public: if (Empty()) return false; - if (NeedSize) - size--; + --size; ElementPtr* tmpptr = read_ptr; read_ptr = tmpptr->next.load(std::memory_order_acquire); @@ -123,7 +121,7 @@ private: // a simple thread-safe, // single reader, multiple writer queue -template +template class MPSCQueue { public: u32 Size() const { @@ -162,7 +160,7 @@ public: } private: - SPSCQueue spsc_queue; + SPSCQueue spsc_queue; std::mutex write_lock; }; } // namespace Common diff --git a/src/core/core_timing.h b/src/core/core_timing.h index 617c7c6d6e..a51c00bbab 100644 --- a/src/core/core_timing.h +++ b/src/core/core_timing.h @@ -218,7 +218,7 @@ private: u64 event_fifo_id = 0; // the queue for storing the events from other threads threadsafe until they will be added // to the event_queue by the emu thread - Common::MPSCQueue ts_queue; + Common::MPSCQueue ts_queue; s64 idled_cycles = 0; // Are we in a function that has been called from Advance() From 0556cac37d6c9e5e25d2620e9038988f912b0d14 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Tue, 12 Feb 2019 22:12:23 -0500 Subject: [PATCH 2/2] threadsafe_queue: Use std::size_t for representing size Makes it consistent with the regular standard containers in terms of size representation. This also gets rid of dependence on our own type aliases, removing the need for an include. --- src/common/threadsafe_queue.h | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/common/threadsafe_queue.h b/src/common/threadsafe_queue.h index c5fb7a27c6..e10baed2ed 100644 --- a/src/common/threadsafe_queue.h +++ b/src/common/threadsafe_queue.h @@ -7,12 +7,11 @@ // a simple lockless thread-safe, // single reader, single writer queue -#include #include #include #include #include -#include "common/common_types.h" +#include namespace Common { template @@ -26,7 +25,7 @@ public: delete read_ptr; } - u32 Size() const { + std::size_t Size() const { return size.load(); } @@ -47,9 +46,9 @@ public: ElementPtr* new_ptr = new ElementPtr(); write_ptr->next.store(new_ptr, std::memory_order_release); write_ptr = new_ptr; - cv.notify_one(); - ++size; + + cv.notify_one(); } void Pop() { @@ -99,7 +98,7 @@ private: // and a pointer to the next ElementPtr class ElementPtr { public: - ElementPtr() : next(nullptr) {} + ElementPtr() = default; ~ElementPtr() { ElementPtr* next_ptr = next.load(); @@ -108,12 +107,12 @@ private: } T current; - std::atomic next; + std::atomic next{nullptr}; }; ElementPtr* write_ptr; ElementPtr* read_ptr; - std::atomic size; + std::atomic_size_t size{0}; std::mutex cv_mutex; std::condition_variable cv; }; @@ -124,7 +123,7 @@ private: template class MPSCQueue { public: - u32 Size() const { + std::size_t Size() const { return spsc_queue.Size(); }