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 "xtc_export.h"
35
36#include <stddef.h>
37#include <stdint.h>
38
39#include "xtc.h"
40
41typedef struct xtc_counter xtc_counter_t;
42typedef struct xtc_gauge xtc_gauge_t;
43typedef struct xtc_hist xtc_hist_t;
44
45typedef enum xtc_metric_kind {
46 XTC_METRIC_COUNTER = 0,
47 XTC_METRIC_GAUGE = 1,
48 XTC_METRIC_HIST = 2
49} xtc_metric_kind_t;
50
51typedef int (*xtc_metric_visit_fn)(const char *name,
52 xtc_metric_kind_t kind,
53 const void *handle,
54 void *user);
55
56/*
57 * PUBLIC: int xtc_counter_create __P((const char *, xtc_counter_t **));
58 * PUBLIC: void xtc_counter_destroy __P((xtc_counter_t *));
59 * PUBLIC: void xtc_counter_inc __P((xtc_counter_t *));
60 * PUBLIC: void xtc_counter_add __P((xtc_counter_t *, int64_t));
61 * PUBLIC: uint64_t xtc_counter_read __P((const xtc_counter_t *));
62 *
63 * PUBLIC: int xtc_gauge_create __P((const char *, xtc_gauge_t **));
64 * PUBLIC: void xtc_gauge_destroy __P((xtc_gauge_t *));
65 * PUBLIC: void xtc_gauge_set __P((xtc_gauge_t *, int64_t));
66 * PUBLIC: void xtc_gauge_add __P((xtc_gauge_t *, int64_t));
67 * PUBLIC: int64_t xtc_gauge_read __P((const xtc_gauge_t *));
68 *
69 * PUBLIC: int xtc_hist_create __P((const char *, xtc_hist_t **));
70 * PUBLIC: void xtc_hist_destroy __P((xtc_hist_t *));
71 * PUBLIC: void xtc_hist_record __P((xtc_hist_t *, int64_t));
72 * PUBLIC: int64_t xtc_hist_quantile __P((const xtc_hist_t *, double));
73 * PUBLIC: uint64_t xtc_hist_count __P((const xtc_hist_t *));
74 *
75 * PUBLIC: int xtc_metrics_iterate __P((xtc_metric_visit_fn, void *));
76 * PUBLIC: int xtc_metrics_dump_prometheus __P((int));
77 *
78 * PUBLIC: void xtc_tuning_check __P((void));
79 */
80
81XTC_API int xtc_counter_create(const char *name, xtc_counter_t **out);
82XTC_API void xtc_counter_destroy(xtc_counter_t *c);
83XTC_API void xtc_counter_inc(xtc_counter_t *c);
84XTC_API void xtc_counter_add(xtc_counter_t *c, int64_t delta);
85XTC_API uint64_t xtc_counter_read(const xtc_counter_t *c);
86
87XTC_API int xtc_gauge_create(const char *name, xtc_gauge_t **out);
88XTC_API void xtc_gauge_destroy(xtc_gauge_t *g);
89XTC_API void xtc_gauge_set(xtc_gauge_t *g, int64_t v);
90XTC_API void xtc_gauge_add(xtc_gauge_t *g, int64_t delta);
91XTC_API int64_t xtc_gauge_read(const xtc_gauge_t *g);
92
93XTC_API int xtc_hist_create(const char *name, xtc_hist_t **out);
94XTC_API void xtc_hist_destroy(xtc_hist_t *h);
95XTC_API void xtc_hist_record(xtc_hist_t *h, int64_t value_ns);
96XTC_API int64_t xtc_hist_quantile(const xtc_hist_t *h, double q);
97XTC_API uint64_t xtc_hist_count(const xtc_hist_t *h);
98
99XTC_API int xtc_metrics_iterate(xtc_metric_visit_fn fn, void *user);
100XTC_API int xtc_metrics_dump_prometheus(int fd);
101
102/*
103 * Run libxtc's host-tuning advisor: a battery of cheap, read-only
104 * probes (CPU governor, intel_pstate, transparent hugepages, vm
105 * swappiness, sched autogroup, io_uring-under-seccomp) that each log
106 * one XTC_LOG_INFO line to the xtc_log_default() sink when the host is
107 * NOT in the recommended state for a low-latency runtime. Silent on a
108 * well-tuned host; Linux-only (a no-op elsewhere); never writes /proc
109 * or /sys.
110 *
111 * This is the ONE diagnostic libxtc itself emits through xtc_log, and
112 * it is the intended way to get those lines into an application's log
113 * sink on the xtc_exec / xtc_loop bring-up path (xtc_app_start already
114 * calls it by default; a consumer that stands up carriers via
115 * xtc_exec_init should call xtc_tuning_check() once at startup, after
116 * installing its xtc_log_set_default sink, to receive the advisories).
117 * Otherwise xtc_log is application-fill: libxtc streams no other
118 * internal log lines today. Safe to call more than once.
119 */
120XTC_API void xtc_tuning_check(void);
121
122#endif /* XTC_STATS_H */