RTOS Wrapper
API reference
Loading...
Searching...
No Matches
ErrorHistory.h
Go to the documentation of this file.
1
23#ifndef HF_UTILS_RTOS_WRAP_ERRORHISTORY_H_
24#define HF_UTILS_RTOS_WRAP_ERRORHISTORY_H_
25
26#include <cstddef>
27#include <cstdint>
28#include <cstring>
29#include <mutex>
30#include <type_traits>
31
32#include "RtosMutex.h"
33
34namespace hf {
35
36template <typename Record>
38public:
39 virtual ~ErrorHistoryReader() noexcept = default;
40
42 [[nodiscard]] virtual std::size_t Size() const noexcept = 0;
43
45 [[nodiscard]] virtual std::size_t Capacity() const noexcept = 0;
46
48 [[nodiscard]] virtual uint32_t Seq() const noexcept = 0;
49
51 [[nodiscard]] virtual uint32_t OverwriteCount() const noexcept = 0;
52
57 virtual std::size_t Snapshot(Record* out, std::size_t max_out) const noexcept = 0;
58};
59
60template <typename Record>
62public:
63 virtual ~ErrorHistoryWriter() noexcept = default;
64
66 virtual bool Push(const Record& record) noexcept = 0;
67
69 virtual bool Pop(Record& out) noexcept = 0;
70
72 virtual bool Clear() noexcept = 0;
73};
74
75template <typename Record, std::size_t kCapacity>
76class ErrorHistory final
77 : public ErrorHistoryReader<Record>
78 , public ErrorHistoryWriter<Record>
79{
80 static_assert(kCapacity > 0, "ErrorHistory kCapacity must be > 0");
81 static_assert(std::is_trivially_copyable_v<Record>,
82 "ErrorHistory<Record, N> requires a trivially copyable Record");
83
84public:
85 ErrorHistory() noexcept = default;
86
87 ErrorHistory(const ErrorHistory&) = delete;
88 ErrorHistory& operator=(const ErrorHistory&) = delete;
89
90 /* ── Writer ──────────────────────────────────────────────────── */
91
92 bool Push(const Record& record) noexcept override
93 {
94 std::lock_guard<RtosMutex> guard(mutex_);
95 std::memcpy(&records_[head_], &record, sizeof(Record));
96 head_ = (head_ + 1U) % kCapacity;
97 if (size_ < kCapacity) {
98 ++size_;
99 } else {
100 tail_ = (tail_ + 1U) % kCapacity;
101 ++overwrite_count_;
102 }
103 ++seq_;
104 return true;
105 }
106
107 bool Pop(Record& out) noexcept override
108 {
109 std::lock_guard<RtosMutex> guard(mutex_);
110 if (size_ == 0U) return false;
111 std::memcpy(&out, &records_[tail_], sizeof(Record));
112 tail_ = (tail_ + 1U) % kCapacity;
113 --size_;
114 ++seq_;
115 return true;
116 }
117
118 bool Clear() noexcept override
119 {
120 std::lock_guard<RtosMutex> guard(mutex_);
121 head_ = tail_ = size_ = 0U;
122 ++seq_;
123 return true;
124 }
125
126 /* ── Reader ──────────────────────────────────────────────────── */
127
128 [[nodiscard]] std::size_t Size() const noexcept override
129 {
130 std::lock_guard<RtosMutex> guard(mutex_);
131 return size_;
132 }
133
134 [[nodiscard]] std::size_t Capacity() const noexcept override
135 {
136 return kCapacity;
137 }
138
139 [[nodiscard]] uint32_t Seq() const noexcept override
140 {
141 std::lock_guard<RtosMutex> guard(mutex_);
142 return seq_;
143 }
144
145 [[nodiscard]] uint32_t OverwriteCount() const noexcept override
146 {
147 std::lock_guard<RtosMutex> guard(mutex_);
148 return overwrite_count_;
149 }
150
151 std::size_t Snapshot(Record* out, std::size_t max_out) const noexcept override
152 {
153 if (out == nullptr || max_out == 0U) return 0U;
154 std::lock_guard<RtosMutex> guard(mutex_);
155 const std::size_t n = (size_ < max_out) ? size_ : max_out;
156 std::size_t idx = tail_;
157 for (std::size_t i = 0; i < n; ++i) {
158 std::memcpy(&out[i], &records_[idx], sizeof(Record));
159 idx = (idx + 1U) % kCapacity;
160 }
161 return n;
162 }
163
164private:
165 mutable RtosMutex mutex_{};
166 Record records_[kCapacity]{};
167 std::size_t head_{0};
168 std::size_t tail_{0};
169 std::size_t size_{0};
170 uint32_t seq_{0};
171 uint32_t overwrite_count_{0};
172};
173
174} // namespace hf
175
176#endif /* HF_UTILS_RTOS_WRAP_ERRORHISTORY_H_ */
Cross-platform RTOS mutex and synchronization primitives.
Definition RtosMutex.h:76
Definition ErrorHistory.h:79
std::size_t Snapshot(Record *out, std::size_t max_out) const noexcept override
Copy up to max_out records into out, oldest first.
Definition ErrorHistory.h:151
bool Clear() noexcept override
Drop all records.
Definition ErrorHistory.h:118
std::size_t Capacity() const noexcept override
Maximum number of entries the ring can hold.
Definition ErrorHistory.h:134
uint32_t OverwriteCount() const noexcept override
Number of Push calls that overwrote an older entry.
Definition ErrorHistory.h:145
std::size_t Size() const noexcept override
Number of entries currently held (≤ Capacity()).
Definition ErrorHistory.h:128
uint32_t Seq() const noexcept override
Monotonic counter; bumps on every successful Push / Pop / Clear.
Definition ErrorHistory.h:139
bool Pop(Record &out) noexcept override
Pop oldest record into out; returns false if empty.
Definition ErrorHistory.h:107
ErrorHistory() noexcept=default
Definition ErrorHistory.h:37
virtual std::size_t Size() const noexcept=0
Number of entries currently held (≤ Capacity()).
virtual uint32_t OverwriteCount() const noexcept=0
Number of Push calls that overwrote an older entry.
virtual std::size_t Capacity() const noexcept=0
Maximum number of entries the ring can hold.
virtual uint32_t Seq() const noexcept=0
Monotonic counter; bumps on every successful Push / Pop / Clear.
virtual std::size_t Snapshot(Record *out, std::size_t max_out) const noexcept=0
Copy up to max_out records into out, oldest first.
virtual ~ErrorHistoryReader() noexcept=default
Definition ErrorHistory.h:61
virtual ~ErrorHistoryWriter() noexcept=default
Definition ErrorHistory.h:34