summaryrefslogtreecommitdiff
path: root/src/common/ring_buffer.h
diff options
context:
space:
mode:
authorGravatar MerryMage2021-02-06 19:13:03 +0000
committerGravatar MerryMage2021-02-06 19:16:00 +0000
commit8d002659987cd45cb77896fbb173159398138e73 (patch)
tree35d6d7a67ebccfbc78f6e0d07600ea9ceb0d909b /src/common/ring_buffer.h
parentarm_dynarmic_32: Print out CPSR.T on exception (diff)
downloadyuzu-8d002659987cd45cb77896fbb173159398138e73.tar.gz
yuzu-8d002659987cd45cb77896fbb173159398138e73.tar.xz
yuzu-8d002659987cd45cb77896fbb173159398138e73.zip
ring_buffer: Remove granularity template argument
Non-obvious bug in RingBuffer::Push(std::vector<T>&) when granularity != 1 Just remove it altogether because we do not have a use for granularity != 1
Diffstat (limited to '')
-rw-r--r--src/common/ring_buffer.h21
1 files changed, 10 insertions, 11 deletions
diff --git a/src/common/ring_buffer.h b/src/common/ring_buffer.h
index 138fa0131..4a8d09806 100644
--- a/src/common/ring_buffer.h
+++ b/src/common/ring_buffer.h
@@ -19,15 +19,14 @@ namespace Common {
19/// SPSC ring buffer 19/// SPSC ring buffer
20/// @tparam T Element type 20/// @tparam T Element type
21/// @tparam capacity Number of slots in ring buffer 21/// @tparam capacity Number of slots in ring buffer
22/// @tparam granularity Slot size in terms of number of elements 22template <typename T, std::size_t capacity>
23template <typename T, std::size_t capacity, std::size_t granularity = 1>
24class RingBuffer { 23class RingBuffer {
25 /// A "slot" is made of `granularity` elements of `T`. 24 /// A "slot" is made of a single `T`.
26 static constexpr std::size_t slot_size = granularity * sizeof(T); 25 static constexpr std::size_t slot_size = sizeof(T);
27 // T must be safely memcpy-able and have a trivial default constructor. 26 // T must be safely memcpy-able and have a trivial default constructor.
28 static_assert(std::is_trivial_v<T>); 27 static_assert(std::is_trivial_v<T>);
29 // Ensure capacity is sensible. 28 // Ensure capacity is sensible.
30 static_assert(capacity < std::numeric_limits<std::size_t>::max() / 2 / granularity); 29 static_assert(capacity < std::numeric_limits<std::size_t>::max() / 2);
31 static_assert((capacity & (capacity - 1)) == 0, "capacity must be a power of two"); 30 static_assert((capacity & (capacity - 1)) == 0, "capacity must be a power of two");
32 // Ensure lock-free. 31 // Ensure lock-free.
33 static_assert(std::atomic_size_t::is_always_lock_free); 32 static_assert(std::atomic_size_t::is_always_lock_free);
@@ -47,7 +46,7 @@ public:
47 const std::size_t second_copy = push_count - first_copy; 46 const std::size_t second_copy = push_count - first_copy;
48 47
49 const char* in = static_cast<const char*>(new_slots); 48 const char* in = static_cast<const char*>(new_slots);
50 std::memcpy(m_data.data() + pos * granularity, in, first_copy * slot_size); 49 std::memcpy(m_data.data() + pos, in, first_copy * slot_size);
51 in += first_copy * slot_size; 50 in += first_copy * slot_size;
52 std::memcpy(m_data.data(), in, second_copy * slot_size); 51 std::memcpy(m_data.data(), in, second_copy * slot_size);
53 52
@@ -74,7 +73,7 @@ public:
74 const std::size_t second_copy = pop_count - first_copy; 73 const std::size_t second_copy = pop_count - first_copy;
75 74
76 char* out = static_cast<char*>(output); 75 char* out = static_cast<char*>(output);
77 std::memcpy(out, m_data.data() + pos * granularity, first_copy * slot_size); 76 std::memcpy(out, m_data.data() + pos, first_copy * slot_size);
78 out += first_copy * slot_size; 77 out += first_copy * slot_size;
79 std::memcpy(out, m_data.data(), second_copy * slot_size); 78 std::memcpy(out, m_data.data(), second_copy * slot_size);
80 79
@@ -84,9 +83,9 @@ public:
84 } 83 }
85 84
86 std::vector<T> Pop(std::size_t max_slots = ~std::size_t(0)) { 85 std::vector<T> Pop(std::size_t max_slots = ~std::size_t(0)) {
87 std::vector<T> out(std::min(max_slots, capacity) * granularity); 86 std::vector<T> out(std::min(max_slots, capacity));
88 const std::size_t count = Pop(out.data(), out.size() / granularity); 87 const std::size_t count = Pop(out.data(), out.size());
89 out.resize(count * granularity); 88 out.resize(count);
90 return out; 89 return out;
91 } 90 }
92 91
@@ -113,7 +112,7 @@ private:
113 alignas(128) std::atomic_size_t m_write_index{0}; 112 alignas(128) std::atomic_size_t m_write_index{0};
114#endif 113#endif
115 114
116 std::array<T, granularity * capacity> m_data; 115 std::array<T, capacity> m_data;
117}; 116};
118 117
119} // namespace Common 118} // namespace Common