11#if DETWS_ENABLE_FAILSAFE
22 DetwsFailsafeCb cb =
nullptr;
23 void *cb_arg =
nullptr;
28size_t u32_dec(uint32_t v,
char *out)
34 tmp[n++] = (char)(
'0' + v % 10);
37 for (
size_t i = 0; i < n; i++)
38 out[i] = tmp[n - 1 - i];
43void detws_failsafe_reset(
void)
46 s_fs.lines[i] = DetwsLifeline{};
48 s_fs.cb_arg =
nullptr;
51int detws_failsafe_register_at(
const char *name, uint32_t deadline_ms, uint32_t now)
55 if (!s_fs.lines[i].armed)
57 s_fs.lines[i].name = name;
58 s_fs.lines[i].deadline_ms = deadline_ms;
59 s_fs.lines[i].last_feed_ms = now;
60 s_fs.lines[i].armed =
true;
61 s_fs.lines[i].breached =
false;
68int detws_failsafe_register(
const char *name, uint32_t deadline_ms)
70 return detws_failsafe_register_at(name, deadline_ms,
detws_millis());
73bool detws_failsafe_feed_at(
int id, uint32_t now)
77 s_fs.lines[id].last_feed_ms = now;
78 s_fs.lines[id].breached =
false;
82bool detws_failsafe_feed(
int id)
87void detws_failsafe_on_breach(DetwsFailsafeCb cb,
void *arg)
93uint32_t detws_failsafe_check_at(uint32_t now)
98 DetwsLifeline &l = s_fs.lines[i];
101 if (!detws_lifeline_overdue(now, l.last_feed_ms, l.deadline_ms))
108 s_fs.cb(i, l.name, s_fs.cb_arg);
113uint32_t detws_failsafe_check(
void)
119static void fs_put(
char *out,
size_t cap,
size_t *n,
const char *s)
121 while (*s && *n + 1 < cap)
125static void fs_put_u32(
char *out,
size_t cap,
size_t *n, uint32_t v)
128 size_t k = u32_dec(v, b);
129 for (
size_t i = 0; i < k && *n + 1 < cap; i++)
133int detws_failsafe_json_at(uint32_t now,
char *out,
size_t cap)
136 if (!out || cap == 0)
139 fs_put(out, cap, &n,
"{\"lifelines\":[");
143 DetwsLifeline &l = s_fs.lines[i];
147 fs_put(out, cap, &n,
",");
149 fs_put(out, cap, &n,
"{\"name\":\"");
150 fs_put(out, cap, &n, l.name ? l.name :
"");
151 fs_put(out, cap, &n,
"\",\"overdue\":");
152 fs_put(out, cap, &n, detws_lifeline_overdue(now, l.last_feed_ms, l.deadline_ms) ?
"true" :
"false");
153 fs_put(out, cap, &n,
",\"age_ms\":");
154 fs_put_u32(out, cap, &n, now - l.last_feed_ms);
155 fs_put(out, cap, &n,
",\"deadline_ms\":");
156 fs_put_u32(out, cap, &n, l.deadline_ms);
157 fs_put(out, cap, &n,
"}");
159 fs_put(out, cap, &n,
"]}");
160 out[n < cap ? n : cap - 1] =
'\0';
#define DETWS_FAILSAFE_MAX_LIFELINES
Max monitored lifelines in the fail-safe registry (static, zero-heap).
Pluggable monotonic clock for all library timing.
uint32_t detws_millis(void)
The library's monotonic time at 1000 Hz (milliseconds).
Software watchdog: deadlock detection + fail-safe safe-state (DETWS_ENABLE_FAILSAFE).