libxtc 0.4.0
Async concurrency for C: Tokio + Seastar + BEAM, in one library
Loading...
Searching...
No Matches
xtc_inspect.h
1/*-
2 * Copyright (c) 2026, The XTC Project
3 * Use of this source code is governed by the ISC License.
4 *
5 * src/inc/xtc_inspect.h
6 * Live process introspection -- the programmatic form of the
7 * debugger's xtc-procs / xtc-loops, callable from a running program
8 * (an admin command, a metrics scraper, a TUI). Modeled on
9 * Erlang's erlang:process_info/2 + the data observer renders.
10 *
11 * Each call takes a best-effort snapshot under the per-loop slot
12 * locks: the proc set is consistent for the duration of the call,
13 * the per-proc counters are read under the mailbox lock, and the
14 * scheduler-owned run state is sampled (it may change the instant
15 * after). Callbacks run AFTER all internal locks are released, so
16 * they may freely call back into the proc/loop APIs.
17 *
18 * See docs/guide/debugging.md.
19 */
20
21#ifndef XTC_INSPECT_H
22#define XTC_INSPECT_H
23
24#include <stddef.h>
25#include <stdint.h>
26
27#include "xtc.h"
28#include "xtc_proc.h"
29
30/* Run state of a proc (mirrors the scheduler task state). */
31enum xtc_proc_run_state {
32 XTC_PROC_SCHEDULED = 0,
33 XTC_PROC_RUNNING = 1,
34 XTC_PROC_PARKED = 2,
35 XTC_PROC_DONE = 3
36};
37
38/* Why a PARKED proc is parked (XTC_PARK_NONE otherwise). */
39enum xtc_proc_park {
40 XTC_PARK_NONE = 0,
41 XTC_PARK_FD = 1,
42 XTC_PARK_TIMER = 2,
43 XTC_PARK_MAILBOX = 3
44};
45
46/*
47 * One proc's snapshot. mbox_len is the live mailbox depth -- the
48 * single most useful health signal in a message-passing system; a
49 * large or growing value is the most common pathology.
50 */
51typedef struct xtc_proc_info {
52 xtc_pid_t pid;
53 int run_state; /* enum xtc_proc_run_state */
54 int park_reason; /* enum xtc_proc_park (valid if PARKED) */
55 int alive;
56 int kill_pending;
57 size_t mbox_len; /* current depth */
58 size_t mbox_peak; /* high-water mark */
59 size_t mbox_cap;
60 size_t mbox_saved; /* selective-receive save queue */
61 uint64_t mbox_recv_total; /* messages ever accepted */
62 uint64_t mbox_drop_total; /* messages ever rejected (full/dead) */
64
65/*
66 * Link/monitor topology is intentionally NOT in the live snapshot: a
67 * proc mutates its own link/monitor lists without a lock, so walking
68 * them from another thread would race. Use the debugger (xtc-proc,
69 * which runs against a stopped program) to inspect link/monitor
70 * topology; the live API reports only fields that are safe to read
71 * concurrently (mailbox counters under the mailbox lock, plus the
72 * sampled run state).
73 */
74
75/* One loop's scheduler snapshot. */
76typedef struct xtc_loop_info {
77 int loop_id; /* 0 standalone, exec slot + 1 otherwise */
78 int n_procs; /* live procs homed on this loop */
79 int n_alive; /* live tasks (procs + plain tasks) */
80 uint64_t tasks_run;
81 uint64_t steals;
83
84/* Enumeration callbacks: return 0 to continue, nonzero to stop early. */
85typedef int (*xtc_inspect_proc_fn)(const xtc_proc_info_t *info, void *user);
86typedef int (*xtc_inspect_loop_fn)(const xtc_loop_info_t *info, void *user);
87
88/*
89 * PUBLIC: int xtc_inspect_procs __P((xtc_inspect_proc_fn, void *));
90 * PUBLIC: int xtc_inspect_loops __P((xtc_inspect_loop_fn, void *));
91 * PUBLIC: int xtc_proc_info __P((xtc_pid_t, xtc_proc_info_t *));
92 */
93
94/* Invoke `cb` once per live proc (across all loops). Returns the
95 * number of procs visited, or a negative XTC_E_* on error. */
96int xtc_inspect_procs(xtc_inspect_proc_fn cb, void *user);
97
98/* Invoke `cb` once per registered loop. Returns the loop count or a
99 * negative XTC_E_*. */
100int xtc_inspect_loops(xtc_inspect_loop_fn cb, void *user);
101
102/* Snapshot one proc by pid into *out. XTC_OK on success,
103 * XTC_E_NOTFOUND if no live proc has that pid, XTC_E_INVAL on a NULL
104 * out-pointer. */
105int xtc_proc_info(xtc_pid_t pid, xtc_proc_info_t *out);
106
107#endif /* XTC_INSPECT_H */