halx
読み取り中…
検索中…
一致する文字列を見つけられません
ring_buffer.hpp
[詳解]
1#pragma once
2
3#include <atomic>
4#include <cstddef>
5#include <optional>
6#include <vector>
7
8#include "common.hpp"
9#include "timeout.hpp"
10
11namespace halx::core {
12
13template <class T> class RingBuffer {
14public:
15 RingBuffer(size_t capacity) : buf_(capacity + 1) {}
16
17 bool push(const T &value) {
18 size_t write_idx = write_idx_.load(std::memory_order_relaxed);
19 size_t next_idx = (write_idx + 1) % buf_.size();
20 if (next_idx == read_idx_.load(std::memory_order_acquire)) {
21 return false;
22 }
23 buf_[write_idx] = value;
24 write_idx_.store(next_idx, std::memory_order_release);
25 return true;
26 }
27
28 std::optional<T> pop() {
29 size_t write_idx = write_idx_.load(std::memory_order_acquire);
30 size_t read_idx = read_idx_.load(std::memory_order_relaxed);
31 if (write_idx == read_idx) {
32 return std::nullopt;
33 }
34 std::optional<T> value = std::move(buf_[read_idx]);
35 size_t next_idx = (read_idx + 1) % buf_.size();
36 read_idx_.store(next_idx, std::memory_order_release);
37 return value;
38 }
39
40 std::optional<T> pop(uint32_t timeout) {
41 core::TimeoutHelper timeout_helper{timeout};
42 std::optional<T> value;
43 while (!(value = pop())) {
44 if (timeout_helper.is_timeout()) {
45 return std::nullopt;
46 }
47 yield();
48 }
49 return value;
50 }
51
52 void clear() {
53 write_idx_.store(0, std::memory_order_relaxed);
54 read_idx_.store(0, std::memory_order_relaxed);
55 }
56
57 size_t size() const {
58 size_t write_idx = write_idx_.load(std::memory_order_acquire);
59 size_t read_idx = read_idx_.load(std::memory_order_relaxed);
60 return (write_idx + buf_.size() - read_idx) % buf_.size();
61 }
62
63 size_t capacity() const { return buf_.size() - 1; }
64
65private:
66 std::vector<T> buf_;
67 std::atomic<size_t> write_idx_{0};
68 std::atomic<size_t> read_idx_{0};
69};
70
71} // namespace halx::core
bool push(const T &value)
Definition ring_buffer.hpp:17
size_t size() const
Definition ring_buffer.hpp:57
std::optional< T > pop()
Definition ring_buffer.hpp:28
size_t capacity() const
Definition ring_buffer.hpp:63
RingBuffer(size_t capacity)
Definition ring_buffer.hpp:15
void clear()
Definition ring_buffer.hpp:52
std::optional< T > pop(uint32_t timeout)
Definition ring_buffer.hpp:40
Definition timeout.hpp:9
Definition common.hpp:11
void yield()
Definition common.hpp:46