xtc_preempt(3)
---xtc_preempt(3)
per-worker preemption timer seam
| XTC_PREEMPT(3) | Library Functions Manual | XTC_PREEMPT(3) |
NAME
xtc_preempt_arm,
xtc_preempt_disarm,
xtc_preempt_supported,
xtc_preempt_ticks,
xtc_preempt_tick_pending —
per-worker preemption timer seam
SYNOPSIS
#include
<xtc_preempt.h>
int
xtc_preempt_arm(int64_t
interval_ns);
int
xtc_preempt_disarm(void);
int
xtc_preempt_supported(void);
uint64_t
xtc_preempt_ticks(void);
int
xtc_preempt_tick_pending(void);
DESCRIPTION
These functions manage a per-thread preemption timer -- the seam the libxtc preemption facility is built on (see the preemption design in the project docs). The timer measures the calling thread's own CPU time, so a busy fiber accrues ticks while an idle worker does not.
xtc_preempt_arm()
arms a timer on the calling thread that fires every
interval_ns of that thread's CPU time, delivering an
internal signal to the thread. Re-arming re-sets the interval. It returns
XTC_OK, XTC_E_INVAL for a
non-positive interval, or XTC_E_NOSYS where
per-thread CPU-time timers are unavailable.
xtc_preempt_disarm()
stops and deletes the calling thread's timer; it is safe to call when no
timer is armed.
xtc_preempt_supported()
returns non-zero where the platform provides per-thread CPU-time timers
(Linux, the BSDs, illumos, AIX) and zero otherwise, in which case
xtc_preempt_arm() returns
XTC_E_NOSYS.
xtc_preempt_ticks()
returns the total number of timer ticks the calling thread has observed
since arming -- telemetry, and the metric that confirms the seam works.
xtc_preempt_tick_pending()
returns non-zero if a tick has fired and is unconsumed, clearing the flag.
The cooperative-assisted preemption path consults it at safe points to
decide whether to yield.
RETURN VALUES
The int functions return
XTC_OK on success or a negative
XTC_E_* code as described above.
NOTES
The timer only records ticks; it does not by itself preempt a running fiber. Higher layers of the preemption facility act on the ticks -- cooperatively (a yield at the next safe point) or, when the involuntary path is enabled, via a signal-context involuntary yield. Nothing arms the timer unless a caller opts in, so the cooperative fast path is unchanged when unused.
The involuntary path (enabled by
xtc_preempt_set_involuntary())
is EXPERIMENTAL and off by default. On x86-64 with the ucontext coroutine
substrate (the default build on glibc) it performs a true resumable
involuntary yield -- a fiber in a pure CPU loop with no cooperative yield
points is time-sliced so its loop-mates make progress -- using an on-stack
trampoline that the signal handler redirects the interrupted instruction
pointer to (Go's async-preemption method). On other substrates (the fcontext
substrate used on musl, the Windows fiber substrate) and in the single-file
amalgamation it declines and falls back to the cooperative path. It is
opt-in because a rare livelock has been observed under pathological
all-CPU-bound load; untrusted pure-CPU work can alternatively run on
xtc_osproc(3), an operating-system thread the kernel
preempts.
SEE ALSO
AUTHORS
The XTC Project.
| July 1, 2026 | Debian |