skip to content
==> include/mesh/top_clock.h <==
1/* @ajax/mesh-top-clock: Rust's Instant and Duration as mesh-top uses them. An instant is
2 * nanoseconds on CLOCK_MONOTONIC (or on a virtual clock, for tests that must be repeatable);
3 * durations convert to seconds exactly as Duration::as_secs_f32/as_secs_f64 do, so derived rates
4 * round the same as the Rust's. */
5#ifndef MESH_TOP_CLOCK_H
6#define MESH_TOP_CLOCK_H
7
8#include <stdbool.h>
9#include <stdint.h>
10
11typedef uint64_t mt_instant;  /* ns */
12typedef uint64_t mt_duration; /* ns */
13
14#define MT_MS(n) ((mt_duration)(n) * 1000000u)
15#define MT_SECS(n) ((mt_duration)(n) * 1000000000u)
16
17/* Now: the monotonic clock, or the virtual one while it is on. */
18mt_instant mt_now(void);
19/* Virtual time for tests: on, at ns. */
20void mt_clock_virtual(bool on, uint64_t ns);
21/* Instant::duration_since (saturating: an earlier "now" is a zero duration). */
22static inline mt_duration mt_since(mt_instant now, mt_instant earlier) { return now > earlier ? now - earlier : 0; }
23/* Duration::as_secs_f32 / as_secs_f64. */
24static inline float mt_secs_f32(mt_duration d) {
25    return (float)(d / 1000000000u) + (float)(uint32_t)(d % 1000000000u) / 1e9f;
26}
27static inline double mt_secs_f64(mt_duration d) {
28    return (double)(d / 1000000000u) + (double)(uint32_t)(d % 1000000000u) / 1e9;
29}
30/* Duration::from_secs_f32 (to the nearest ns). */
31mt_duration mt_from_secs_f32(float s);
32
33#endif