summaryrefslogtreecommitdiff
path: root/src/common/ring_buffer.h
diff options
context:
space:
mode:
authorGravatar fearlessTobi2018-09-15 15:21:06 +0200
committerGravatar fearlessTobi2018-09-15 15:21:06 +0200
commit63c2e32e207d31ecadd9022e1d7cd705c9febac8 (patch)
tree8a90e8ef2804f147dff7225a543a8740ecf7160c /src/common/ring_buffer.h
parentMerge pull request #1310 from lioncash/kernel-ns (diff)
downloadyuzu-63c2e32e207d31ecadd9022e1d7cd705c9febac8.tar.gz
yuzu-63c2e32e207d31ecadd9022e1d7cd705c9febac8.tar.xz
yuzu-63c2e32e207d31ecadd9022e1d7cd705c9febac8.zip
Port #4182 from Citra: "Prefix all size_t with std::"
Diffstat (limited to '')
-rw-r--r--src/common/ring_buffer.h50
1 files changed, 25 insertions, 25 deletions
diff --git a/src/common/ring_buffer.h b/src/common/ring_buffer.h
index 30d934a38..45926c9ec 100644
--- a/src/common/ring_buffer.h
+++ b/src/common/ring_buffer.h
@@ -19,31 +19,31 @@ namespace Common {
19/// @tparam T Element type 19/// @tparam T Element type
20/// @tparam capacity Number of slots in ring buffer 20/// @tparam capacity Number of slots in ring buffer
21/// @tparam granularity Slot size in terms of number of elements 21/// @tparam granularity Slot size in terms of number of elements
22template <typename T, size_t capacity, size_t granularity = 1> 22template <typename T, std::size_t capacity, std::size_t granularity = 1>
23class RingBuffer { 23class RingBuffer {
24 /// A "slot" is made of `granularity` elements of `T`. 24 /// A "slot" is made of `granularity` elements of `T`.
25 static constexpr size_t slot_size = granularity * sizeof(T); 25 static constexpr std::size_t slot_size = granularity * sizeof(T);
26 // 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.
27 static_assert(std::is_trivial_v<T>); 27 static_assert(std::is_trivial_v<T>);
28 // Ensure capacity is sensible. 28 // Ensure capacity is sensible.
29 static_assert(capacity < std::numeric_limits<size_t>::max() / 2 / granularity); 29 static_assert(capacity < std::numeric_limits<std::size_t>::max() / 2 / granularity);
30 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");
31 // Ensure lock-free. 31 // Ensure lock-free.
32 static_assert(std::atomic<size_t>::is_always_lock_free); 32 static_assert(std::atomic<std::size_t>::is_always_lock_free);
33 33
34public: 34public:
35 /// Pushes slots into the ring buffer 35 /// Pushes slots into the ring buffer
36 /// @param new_slots Pointer to the slots to push 36 /// @param new_slots Pointer to the slots to push
37 /// @param slot_count Number of slots to push 37 /// @param slot_count Number of slots to push
38 /// @returns The number of slots actually pushed 38 /// @returns The number of slots actually pushed
39 size_t Push(const void* new_slots, size_t slot_count) { 39 std::size_t Push(const void* new_slots, std::size_t slot_count) {
40 const size_t write_index = m_write_index.load(); 40 const std::size_t write_index = m_write_index.load();
41 const size_t slots_free = capacity + m_read_index.load() - write_index; 41 const std::size_t slots_free = capacity + m_read_index.load() - write_index;
42 const size_t push_count = std::min(slot_count, slots_free); 42 const std::size_t push_count = std::min(slot_count, slots_free);
43 43
44 const size_t pos = write_index % capacity; 44 const std::size_t pos = write_index % capacity;
45 const size_t first_copy = std::min(capacity - pos, push_count); 45 const std::size_t first_copy = std::min(capacity - pos, push_count);
46 const size_t second_copy = push_count - first_copy; 46 const std::size_t second_copy = push_count - first_copy;
47 47
48 const char* in = static_cast<const char*>(new_slots); 48 const char* in = static_cast<const char*>(new_slots);
49 std::memcpy(m_data.data() + pos * granularity, in, first_copy * slot_size); 49 std::memcpy(m_data.data() + pos * granularity, in, first_copy * slot_size);
@@ -55,7 +55,7 @@ public:
55 return push_count; 55 return push_count;
56 } 56 }
57 57
58 size_t Push(const std::vector<T>& input) { 58 std::size_t Push(const std::vector<T>& input) {
59 return Push(input.data(), input.size()); 59 return Push(input.data(), input.size());
60 } 60 }
61 61
@@ -63,14 +63,14 @@ public:
63 /// @param output Where to store the popped slots 63 /// @param output Where to store the popped slots
64 /// @param max_slots Maximum number of slots to pop 64 /// @param max_slots Maximum number of slots to pop
65 /// @returns The number of slots actually popped 65 /// @returns The number of slots actually popped
66 size_t Pop(void* output, size_t max_slots = ~size_t(0)) { 66 std::size_t Pop(void* output, std::size_t max_slots = ~std::size_t(0)) {
67 const size_t read_index = m_read_index.load(); 67 const std::size_t read_index = m_read_index.load();
68 const size_t slots_filled = m_write_index.load() - read_index; 68 const std::size_t slots_filled = m_write_index.load() - read_index;
69 const size_t pop_count = std::min(slots_filled, max_slots); 69 const std::size_t pop_count = std::min(slots_filled, max_slots);
70 70
71 const size_t pos = read_index % capacity; 71 const std::size_t pos = read_index % capacity;
72 const size_t first_copy = std::min(capacity - pos, pop_count); 72 const std::size_t first_copy = std::min(capacity - pos, pop_count);
73 const size_t second_copy = pop_count - first_copy; 73 const std::size_t second_copy = pop_count - first_copy;
74 74
75 char* out = static_cast<char*>(output); 75 char* out = static_cast<char*>(output);
76 std::memcpy(out, m_data.data() + pos * granularity, first_copy * slot_size); 76 std::memcpy(out, m_data.data() + pos * granularity, first_copy * slot_size);
@@ -82,28 +82,28 @@ public:
82 return pop_count; 82 return pop_count;
83 } 83 }
84 84
85 std::vector<T> Pop(size_t max_slots = ~size_t(0)) { 85 std::vector<T> Pop(std::size_t max_slots = ~std::size_t(0)) {
86 std::vector<T> out(std::min(max_slots, capacity) * granularity); 86 std::vector<T> out(std::min(max_slots, capacity) * granularity);
87 const size_t count = Pop(out.data(), out.size() / granularity); 87 const std::size_t count = Pop(out.data(), out.size() / granularity);
88 out.resize(count * granularity); 88 out.resize(count * granularity);
89 return out; 89 return out;
90 } 90 }
91 91
92 /// @returns Number of slots used 92 /// @returns Number of slots used
93 size_t Size() const { 93 std::size_t Size() const {
94 return m_write_index.load() - m_read_index.load(); 94 return m_write_index.load() - m_read_index.load();
95 } 95 }
96 96
97 /// @returns Maximum size of ring buffer 97 /// @returns Maximum size of ring buffer
98 constexpr size_t Capacity() const { 98 constexpr std::size_t Capacity() const {
99 return capacity; 99 return capacity;
100 } 100 }
101 101
102private: 102private:
103 // It is important to align the below variables for performance reasons: 103 // It is important to align the below variables for performance reasons:
104 // Having them on the same cache-line would result in false-sharing between them. 104 // Having them on the same cache-line would result in false-sharing between them.
105 alignas(128) std::atomic<size_t> m_read_index{0}; 105 alignas(128) std::atomic<std::size_t> m_read_index{0};
106 alignas(128) std::atomic<size_t> m_write_index{0}; 106 alignas(128) std::atomic<std::size_t> m_write_index{0};
107 107
108 std::array<T, granularity * capacity> m_data; 108 std::array<T, granularity * capacity> m_data;
109}; 109};