Corium 1.1.0
High-Performance Zero-Heap C++20 MPSC Application Runtime
Loading...
Searching...
No Matches
HeartbeatMonitor.hpp
Go to the documentation of this file.
1
7#pragma once
8
9#include <array>
10#include <atomic>
11#include <cstddef>
12#include <cstdint>
13
14namespace corium::safety {
15
20template <std::size_t MaxServices = 16>
22public:
23 struct alignas(32) ServiceEntry {
24 uint32_t serviceId{0};
25 uint64_t timeoutNs{0};
26 std::atomic<uint64_t> lastHeartbeatNs{0};
27 std::atomic<bool> active{false};
28 };
29
30 HeartbeatMonitor() = default;
31
37 bool registerService(uint32_t serviceId, uint64_t timeoutNs, uint64_t initialTimestampNs = 0) noexcept
38 {
39 for (std::size_t i = 0; i < MaxServices; ++i) {
40 bool expected = false;
41 if (_services[i].active.compare_exchange_strong(expected, true, std::memory_order_relaxed)) {
42 _services[i].serviceId = serviceId;
43 _services[i].timeoutNs = timeoutNs;
44 _services[i].lastHeartbeatNs.store(initialTimestampNs, std::memory_order_release);
45 return true;
46 }
47 if (_services[i].serviceId == serviceId && expected) {
48 // Already registered; update timeout and baseline
49 _services[i].timeoutNs = timeoutNs;
50 _services[i].lastHeartbeatNs.store(initialTimestampNs, std::memory_order_release);
51 return true;
52 }
53 }
54 return false;
55 }
56
60 void beat(uint32_t serviceId, uint64_t nowNs) noexcept
61 {
62 for (std::size_t i = 0; i < MaxServices; ++i) {
63 if (_services[i].active.load(std::memory_order_relaxed) && _services[i].serviceId == serviceId) {
64 _services[i].lastHeartbeatNs.store(nowNs, std::memory_order_release);
65 return;
66 }
67 }
68 }
69
71 void unregisterService(uint32_t serviceId) noexcept
72 {
73 for (std::size_t i = 0; i < MaxServices; ++i) {
74 if (_services[i].serviceId == serviceId) {
75 _services[i].active.store(false, std::memory_order_release);
76 return;
77 }
78 }
79 }
80
87 [[nodiscard]] bool checkHealth(
88 uint64_t nowNs,
89 uint32_t& outTimedOutServiceId,
90 uint64_t& outLastHeartbeatNs,
91 uint64_t& outTimeoutBudgetNs
92 ) const noexcept
93 {
94 for (std::size_t i = 0; i < MaxServices; ++i) {
95 if (_services[i].active.load(std::memory_order_acquire)) {
96 const uint64_t last = _services[i].lastHeartbeatNs.load(std::memory_order_acquire);
97 const uint64_t limit = _services[i].timeoutNs;
98 if (nowNs > last && (nowNs - last) > limit) {
99 outTimedOutServiceId = _services[i].serviceId;
100 outLastHeartbeatNs = last;
101 outTimeoutBudgetNs = limit;
102 return false;
103 }
104 }
105 }
106 return true;
107 }
108
110 [[nodiscard]] constexpr std::size_t maxServices() const noexcept
111 {
112 return MaxServices;
113 }
114
115private:
116 std::array<ServiceEntry, MaxServices> _services{};
117};
118
119} // namespace corium::safety
Zero-heap multi-service heartbeat tracker for safety-critical execution. Thread-safe for concurrent h...
Definition HeartbeatMonitor.hpp:21
bool checkHealth(uint64_t nowNs, uint32_t &outTimedOutServiceId, uint64_t &outLastHeartbeatNs, uint64_t &outTimeoutBudgetNs) const noexcept
Check health status of all registered active services.
Definition HeartbeatMonitor.hpp:87
constexpr std::size_t maxServices() const noexcept
Get maximum capacity of monitored services.
Definition HeartbeatMonitor.hpp:110
bool registerService(uint32_t serviceId, uint64_t timeoutNs, uint64_t initialTimestampNs=0) noexcept
Register a service for heartbeat monitoring with a specified timeout.
Definition HeartbeatMonitor.hpp:37
void unregisterService(uint32_t serviceId) noexcept
Unregister a service from active monitoring.
Definition HeartbeatMonitor.hpp:71
void beat(uint32_t serviceId, uint64_t nowNs) noexcept
Record a heartbeat for a given service.
Definition HeartbeatMonitor.hpp:60
Definition CircuitBreaker.hpp:13
Definition HeartbeatMonitor.hpp:23
uint32_t serviceId
Definition HeartbeatMonitor.hpp:24
std::atomic< uint64_t > lastHeartbeatNs
Definition HeartbeatMonitor.hpp:26
uint64_t timeoutNs
Definition HeartbeatMonitor.hpp:25
std::atomic< bool > active
Definition HeartbeatMonitor.hpp:27