libxtc 0.4.0
Async concurrency for C: Tokio + Seastar + BEAM, in one library
Loading...
Searching...
No Matches
xtc_stats.h
1/*-
2 * Copyright (c) 2026, The XTC Project
3 * Use of this source code is governed by the ISC License,
4 * a copy of which is in the file LICENSE in the top-level directory
5 * of this distribution.
6 *
7 * src/inc/xtc_stats.h
8 * Runtime statistics primitives: counters, gauges, histograms.
9 * Designed to be cheap to update on the hot path (single atomic
10 * per-CPU shard for counters; one _Atomic for gauges) and
11 * non-obscuring under perf inspection.
12 *
13 * A counter accumulates events. Per-CPU sharded so that
14 * xtc_counter_inc compiles to one cache-line-local atomic add.
15 * Cross-CPU summing happens only on read, which is the slow path.
16 *
17 * A gauge holds a current value (depth, queue length, etc.).
18 * Single _Atomic int64; reads are wait-free, writes are atomic
19 * store. For low-frequency-update gauges this is fine.
20 *
21 * A histogram tracks a value distribution and answers quantile
22 * queries (p50/p99/p999). The current implementation wraps the
23 * HDR-style hist used by the conformance bench, with per-CPU
24 * shards so concurrent record() calls don't contend. Quantile
25 * queries merge shards under a read lock.
26 *
27 * A registry walks every metric for periodic dumps to logs or
28 * a Prometheus-style scrape endpoint.
29 */
30
31#ifndef XTC_STATS_H
32#define XTC_STATS_H
33
34#include <stddef.h>
35#include <stdint.h>
36
37#include "xtc.h"
38
39typedef struct xtc_counter xtc_counter_t;
40typedef struct xtc_gauge xtc_gauge_t;
41typedef struct xtc_hist xtc_hist_t;
42
43typedef enum xtc_metric_kind {
44 XTC_METRIC_COUNTER = 0,
45 XTC_METRIC_GAUGE = 1,
46 XTC_METRIC_HIST = 2
47} xtc_metric_kind_t;
48
49typedef int (*xtc_metric_visit_fn)(const char *name,
50 xtc_metric_kind_t kind,
51 const void *handle,
52 void *user);
53
54/*
55 * PUBLIC: int xtc_counter_create __P((const char *, xtc_counter_t **));
56 * PUBLIC: void xtc_counter_destroy __P((xtc_counter_t *));
57 * PUBLIC: void xtc_counter_inc __P((xtc_counter_t *));
58 * PUBLIC: void xtc_counter_add __P((xtc_counter_t *, int64_t));
59 * PUBLIC: uint64_t xtc_counter_read __P((const xtc_counter_t *));
60 *
61 * PUBLIC: int xtc_gauge_create __P((const char *, xtc_gauge_t **));
62 * PUBLIC: void xtc_gauge_destroy __P((xtc_gauge_t *));
63 * PUBLIC: void xtc_gauge_set __P((xtc_gauge_t *, int64_t));
64 * PUBLIC: void xtc_gauge_add __P((xtc_gauge_t *, int64_t));
65 * PUBLIC: int64_t xtc_gauge_read __P((const xtc_gauge_t *));
66 *
67 * PUBLIC: int xtc_hist_create __P((const char *, xtc_hist_t **));
68 * PUBLIC: void xtc_hist_destroy __P((xtc_hist_t *));
69 * PUBLIC: void xtc_hist_record __P((xtc_hist_t *, int64_t));
70 * PUBLIC: int64_t xtc_hist_quantile __P((const xtc_hist_t *, double));
71 * PUBLIC: uint64_t xtc_hist_count __P((const xtc_hist_t *));
72 *
73 * PUBLIC: int xtc_metrics_iterate __P((xtc_metric_visit_fn, void *));
74 * PUBLIC: int xtc_metrics_dump_prometheus __P((int));
75 */
76
77int xtc_counter_create(const char *name, xtc_counter_t **out);
78void xtc_counter_destroy(xtc_counter_t *c);
79void xtc_counter_inc(xtc_counter_t *c);
80void xtc_counter_add(xtc_counter_t *c, int64_t delta);
81uint64_t xtc_counter_read(const xtc_counter_t *c);
82
83int xtc_gauge_create(const char *name, xtc_gauge_t **out);
84void xtc_gauge_destroy(xtc_gauge_t *g);
85void xtc_gauge_set(xtc_gauge_t *g, int64_t v);
86void xtc_gauge_add(xtc_gauge_t *g, int64_t delta);
87int64_t xtc_gauge_read(const xtc_gauge_t *g);
88
89int xtc_hist_create(const char *name, xtc_hist_t **out);
90void xtc_hist_destroy(xtc_hist_t *h);
91void xtc_hist_record(xtc_hist_t *h, int64_t value_ns);
92int64_t xtc_hist_quantile(const xtc_hist_t *h, double q);
93uint64_t xtc_hist_count(const xtc_hist_t *h);
94
95int xtc_metrics_iterate(xtc_metric_visit_fn fn, void *user);
96int xtc_metrics_dump_prometheus(int fd);
97
98#endif /* XTC_STATS_H */