libxtc 0.4.0
Async concurrency for C: Tokio + Seastar + BEAM, in one library
Loading...
Searching...
No Matches
xtc_probes.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_probes.h
6 * Static (USDT) probe points: the C side of src/xtc_probes.d.
7 * Library-internal; not installed. Every probe site in src/ is one
8 * XTC_PROBE_<NAME>(...) line. Three builds, picked at configure
9 * time (--enable-dtrace, meson -Ddtrace):
10 *
11 * XTC_HAVE_DTRACE the build ran `dtrace -h` over xtc_probes.d into
12 * xtc_probes_dtrace.h (its XTC_ prefix rewritten
13 * to XTC_DT_ so a probe can never collide with a
14 * libxtc macro). FreeBSD, illumos and macOS; also
15 * Linux with the systemtap `dtrace` script, which
16 * adds is-enabled semaphores. Everywhere but macOS
17 * `dtrace -G` then post-processes the objects into
18 * xtc_probes.o (dist/xtc_probes.sh).
19 * XTC_PROBES_SDT header-only <sys/sdt.h> from systemtap (Linux),
20 * no tool and no post-link step. perf, bpftrace,
21 * bcc and SystemTap find the probes from the ELF
22 * notes. There are no semaphores, so
23 * XTC_PROBE_ENABLED() is a constant 1.
24 * neither every macro expands to nothing and no argument
25 * is evaluated: the probes-off build carries no
26 * instruction for them.
27 *
28 * Windows (ETW) is out of scope: there every macro is empty.
29 *
30 * Arguments are cheap by design (registers and plain loads, never a
31 * clock read or a call), because on the XTC_PROBES_SDT path they are
32 * materialized even when no tracer is attached. Wrap anything more
33 * expensive in `if (XTC_PROBE_ENABLED(NAME))`. See xtc_usdt(3).
34 */
35
36#ifndef XTC_PROBES_H
37#define XTC_PROBES_H
38
39#include "xtc_int.h" /* xtc_config.h: XTC_HAVE_DTRACE / XTC_PROBES_SDT */
40
41/* A libxtc pid is TWO probe arguments (2.0: the pid is 16 bytes):
42 * id = loop_id << 32 | local_id, then gen. 0, 0 is XTC_PID_NONE. */
43#define XTC_PROBE_PID_ID(p) \
44 (((uint64_t)(p).loop_id << 32) | (uint64_t)(p).local_id)
45#define XTC_PROBE_PID_GEN(p) ((uint64_t)(p).gen)
46
47/* fiber-park / fiber-resume `reason` (arg1). Stable: documented in
48 * xtc_usdt(3) and decoded by tools/dtrace and tools/bpftrace. */
49#define XTC_PROBE_PARK_MAILBOX 1 /* xtc_recv*; object = 0 */
50#define XTC_PROBE_PARK_SLEEP 2 /* xtc_proc_sleep; object = 0 */
51#define XTC_PROBE_PARK_FD 3 /* xtc_proc_wait_fd; object = fd */
52#define XTC_PROBE_PARK_AIO 4 /* xtc_aio_*; object = xtc_aio_t * */
53#define XTC_PROBE_PARK_BLOCKING 5 /* xtc_blocking_run; object = work */
54#define XTC_PROBE_PARK_SYNC 6 /* amutex/arwlock/sem/notify/barrier/gate */
55#define XTC_PROBE_PARK_LWLOCK 7 /* xtc_lwlock; object = the lock */
56#define XTC_PROBE_PARK_LOCKMGR 8 /* xtc_lockmgr; object = the manager */
57#define XTC_PROBE_PARK_FUTURE 9 /* xtc_future wait; object = the future */
58
59/* fiber-wake `how` (arg2). */
60#define XTC_PROBE_WAKE_LOCAL 0 /* claimed; queued on this thread's loop */
61#define XTC_PROBE_WAKE_REMOTE 1 /* claimed; posted to the loop's inbox */
62#define XTC_PROBE_WAKE_UNPARKED 2 /* not parked: latched for the park
63 * verdict, or already runnable */
64
65/* lock-wait-start / lock-wait-done `kind` (arg1). */
66#define XTC_PROBE_LOCK_AMUTEX 1
67#define XTC_PROBE_LOCK_ARWLOCK 2
68#define XTC_PROBE_LOCK_LWLOCK 3
69#define XTC_PROBE_LOCK_LOCKMGR 4
70
71#if defined(XTC_HAVE_DTRACE) && !defined(_WIN32)
72
73#include "xtc_probes_dtrace.h"
74
75#if defined(XTC_PROBES_ANCHOR)
76/*
77 * `dtrace -G` puts the probe table (DOF) in xtc_probes.o, which nothing
78 * references by name -- so a link against libxtc.a would leave it out
79 * and the probes would silently not exist. Every probe TU references
80 * this anchor, defined in xtc_probes.o, which pulls it in. Set by the
81 * libxtc build only; an amalgamation links xtc.o directly and needs none.
82 */
83extern const char __xtc_probes_anchor __attribute__((visibility("hidden")));
84static const char *const __xtc_probes_ref __attribute__((used)) =
85 &__xtc_probes_anchor;
86#endif
87
88#define XTC_PROBE_ENABLED(name) (XTC_DT_##name##_ENABLED())
89
90#define XTC_PROBE_PROC_SPAWN(a, b, c, d) XTC_DT_PROC_SPAWN(a, b, c, d)
91#define XTC_PROBE_PROC_START(a, b, c) XTC_DT_PROC_START(a, b, c)
92#define XTC_PROBE_PROC_EXIT(a, b, c) XTC_DT_PROC_EXIT(a, b, c)
93#define XTC_PROBE_PROC_KILL(a, b, c) XTC_DT_PROC_KILL(a, b, c)
94#define XTC_PROBE_MSG_SEND(a, b, c, d, e) XTC_DT_MSG_SEND(a, b, c, d, e)
95#define XTC_PROBE_MSG_RECV(a, b, c, d, e) XTC_DT_MSG_RECV(a, b, c, d, e)
96#define XTC_PROBE_FIBER_PARK(a, b, c) XTC_DT_FIBER_PARK(a, b, c)
97#define XTC_PROBE_FIBER_RESUME(a, b, c) XTC_DT_FIBER_RESUME(a, b, c)
98#define XTC_PROBE_FIBER_WAKE(a, b, c) XTC_DT_FIBER_WAKE(a, b, c)
99#define XTC_PROBE_TASK_RUN_START(a, b, c) XTC_DT_TASK_RUN_START(a, b, c)
100#define XTC_PROBE_TASK_RUN_DONE(a, b, c) XTC_DT_TASK_RUN_DONE(a, b, c)
101#define XTC_PROBE_LOOP_POLL(a, b, c) XTC_DT_LOOP_POLL(a, b, c)
102#define XTC_PROBE_IO_DISPATCH(a, b, c, d) XTC_DT_IO_DISPATCH(a, b, c, d)
103#define XTC_PROBE_SCHED_STEAL(a, b, c) XTC_DT_SCHED_STEAL(a, b, c)
104#define XTC_PROBE_TIMER_ARM(a, b, c) XTC_DT_TIMER_ARM(a, b, c)
105#define XTC_PROBE_TIMER_FIRE(a, b, c) XTC_DT_TIMER_FIRE(a, b, c)
106#define XTC_PROBE_TIMER_CANCEL(a) XTC_DT_TIMER_CANCEL(a)
107#define XTC_PROBE_AIO_SUBMIT(a, b, c, d) XTC_DT_AIO_SUBMIT(a, b, c, d)
108#define XTC_PROBE_AIO_DONE(a, b, c) XTC_DT_AIO_DONE(a, b, c)
109#define XTC_PROBE_BLOCKING_ENQUEUE(a, b) XTC_DT_BLOCKING_ENQUEUE(a, b)
110#define XTC_PROBE_BLOCKING_START(a) XTC_DT_BLOCKING_START(a)
111#define XTC_PROBE_BLOCKING_DONE(a, b) XTC_DT_BLOCKING_DONE(a, b)
112#define XTC_PROBE_LOCK_WAIT_START(a, b, c, d) XTC_DT_LOCK_WAIT_START(a, b, c, d)
113#define XTC_PROBE_LOCK_WAIT_DONE(a, b, c, d) XTC_DT_LOCK_WAIT_DONE(a, b, c, d)
114#define XTC_PROBE_SUP_RESTART(a, b, c, d) XTC_DT_SUP_RESTART(a, b, c, d)
115#define XTC_PROBE_PREEMPT_TICK(a) XTC_DT_PREEMPT_TICK(a)
116#define XTC_PROBE_ALLOC_FAIL(a) XTC_DT_ALLOC_FAIL(a)
117#define XTC_PROBE_SLAB_GROW(a, b) XTC_DT_SLAB_GROW(a, b)
118/* dtrace -h drops `const` from string arguments on some platforms. */
119#define XTC_PROBE_SIM_NONDETERMINISM(a) \
120 XTC_DT_SIM_NONDETERMINISM((char *)(uintptr_t)(a))
121#define XTC_PROBE_SIM_BUGGIFY(a, b) \
122 XTC_DT_SIM_BUGGIFY((char *)(uintptr_t)(a), b)
123
124#elif defined(XTC_PROBES_SDT) && !defined(_WIN32)
125
126#include <sys/sdt.h>
127
128#define XTC_PROBE_ENABLED(name) (1)
129
130#define XTC_PROBE_PROC_SPAWN(a, b, c, d) DTRACE_PROBE4(xtc, proc__spawn, a, b, c, d)
131#define XTC_PROBE_PROC_START(a, b, c) DTRACE_PROBE3(xtc, proc__start, a, b, c)
132#define XTC_PROBE_PROC_EXIT(a, b, c) DTRACE_PROBE3(xtc, proc__exit, a, b, c)
133#define XTC_PROBE_PROC_KILL(a, b, c) DTRACE_PROBE3(xtc, proc__kill, a, b, c)
134#define XTC_PROBE_MSG_SEND(a, b, c, d, e) DTRACE_PROBE5(xtc, msg__send, a, b, c, d, e)
135#define XTC_PROBE_MSG_RECV(a, b, c, d, e) DTRACE_PROBE5(xtc, msg__recv, a, b, c, d, e)
136#define XTC_PROBE_FIBER_PARK(a, b, c) DTRACE_PROBE3(xtc, fiber__park, a, b, c)
137#define XTC_PROBE_FIBER_RESUME(a, b, c) DTRACE_PROBE3(xtc, fiber__resume, a, b, c)
138#define XTC_PROBE_FIBER_WAKE(a, b, c) DTRACE_PROBE3(xtc, fiber__wake, a, b, c)
139#define XTC_PROBE_TASK_RUN_START(a, b, c) \
140 DTRACE_PROBE3(xtc, task__run__start, a, b, c)
141#define XTC_PROBE_TASK_RUN_DONE(a, b, c) \
142 DTRACE_PROBE3(xtc, task__run__done, a, b, c)
143#define XTC_PROBE_LOOP_POLL(a, b, c) DTRACE_PROBE3(xtc, loop__poll, a, b, c)
144#define XTC_PROBE_IO_DISPATCH(a, b, c, d) \
145 DTRACE_PROBE4(xtc, io__dispatch, a, b, c, d)
146#define XTC_PROBE_SCHED_STEAL(a, b, c) DTRACE_PROBE3(xtc, sched__steal, a, b, c)
147#define XTC_PROBE_TIMER_ARM(a, b, c) DTRACE_PROBE3(xtc, timer__arm, a, b, c)
148#define XTC_PROBE_TIMER_FIRE(a, b, c) DTRACE_PROBE3(xtc, timer__fire, a, b, c)
149#define XTC_PROBE_TIMER_CANCEL(a) DTRACE_PROBE1(xtc, timer__cancel, a)
150#define XTC_PROBE_AIO_SUBMIT(a, b, c, d) \
151 DTRACE_PROBE4(xtc, aio__submit, a, b, c, d)
152#define XTC_PROBE_AIO_DONE(a, b, c) DTRACE_PROBE3(xtc, aio__done, a, b, c)
153#define XTC_PROBE_BLOCKING_ENQUEUE(a, b) \
154 DTRACE_PROBE2(xtc, blocking__enqueue, a, b)
155#define XTC_PROBE_BLOCKING_START(a) DTRACE_PROBE1(xtc, blocking__start, a)
156#define XTC_PROBE_BLOCKING_DONE(a, b) DTRACE_PROBE2(xtc, blocking__done, a, b)
157#define XTC_PROBE_LOCK_WAIT_START(a, b, c, d) \
158 DTRACE_PROBE4(xtc, lock__wait__start, a, b, c, d)
159#define XTC_PROBE_LOCK_WAIT_DONE(a, b, c, d) \
160 DTRACE_PROBE4(xtc, lock__wait__done, a, b, c, d)
161#define XTC_PROBE_SUP_RESTART(a, b, c, d) DTRACE_PROBE4(xtc, sup__restart, a, b, c, d)
162#define XTC_PROBE_PREEMPT_TICK(a) DTRACE_PROBE1(xtc, preempt__tick, a)
163#define XTC_PROBE_ALLOC_FAIL(a) DTRACE_PROBE1(xtc, alloc__fail, a)
164#define XTC_PROBE_SLAB_GROW(a, b) DTRACE_PROBE2(xtc, slab__grow, a, b)
165#define XTC_PROBE_SIM_NONDETERMINISM(a) \
166 DTRACE_PROBE1(xtc, sim__nondeterminism, a)
167#define XTC_PROBE_SIM_BUGGIFY(a, b) DTRACE_PROBE2(xtc, sim__buggify, a, b)
168
169#else /* probes compiled out */
170
171#define XTC_PROBE_ENABLED(name) (0)
172
173#define XTC_PROBE_PROC_SPAWN(a, b, c, d) do { } while (0)
174#define XTC_PROBE_PROC_START(a, b, c) do { } while (0)
175#define XTC_PROBE_PROC_EXIT(a, b, c) do { } while (0)
176#define XTC_PROBE_PROC_KILL(a, b, c) do { } while (0)
177#define XTC_PROBE_MSG_SEND(a, b, c, d, e) do { } while (0)
178#define XTC_PROBE_MSG_RECV(a, b, c, d, e) do { } while (0)
179#define XTC_PROBE_FIBER_PARK(a, b, c) do { } while (0)
180#define XTC_PROBE_FIBER_RESUME(a, b, c) do { } while (0)
181#define XTC_PROBE_FIBER_WAKE(a, b, c) do { } while (0)
182#define XTC_PROBE_TASK_RUN_START(a, b, c) do { } while (0)
183#define XTC_PROBE_TASK_RUN_DONE(a, b, c) do { } while (0)
184#define XTC_PROBE_LOOP_POLL(a, b, c) do { } while (0)
185#define XTC_PROBE_IO_DISPATCH(a, b, c, d) do { } while (0)
186#define XTC_PROBE_SCHED_STEAL(a, b, c) do { } while (0)
187#define XTC_PROBE_TIMER_ARM(a, b, c) do { } while (0)
188#define XTC_PROBE_TIMER_FIRE(a, b, c) do { } while (0)
189#define XTC_PROBE_TIMER_CANCEL(a) do { } while (0)
190#define XTC_PROBE_AIO_SUBMIT(a, b, c, d) do { } while (0)
191#define XTC_PROBE_AIO_DONE(a, b, c) do { } while (0)
192#define XTC_PROBE_BLOCKING_ENQUEUE(a, b) do { } while (0)
193#define XTC_PROBE_BLOCKING_START(a) do { } while (0)
194#define XTC_PROBE_BLOCKING_DONE(a, b) do { } while (0)
195#define XTC_PROBE_LOCK_WAIT_START(a, b, c, d) do { } while (0)
196#define XTC_PROBE_LOCK_WAIT_DONE(a, b, c, d) do { } while (0)
197#define XTC_PROBE_SUP_RESTART(a, b, c, d) do { } while (0)
198#define XTC_PROBE_PREEMPT_TICK(a) do { } while (0)
199#define XTC_PROBE_ALLOC_FAIL(a) do { } while (0)
200#define XTC_PROBE_SLAB_GROW(a, b) do { } while (0)
201#define XTC_PROBE_SIM_NONDETERMINISM(a) do { } while (0)
202#define XTC_PROBE_SIM_BUGGIFY(a, b) do { } while (0)
203
204#endif
205
206#endif /* XTC_PROBES_H */