libxtc
0.4.0
Async concurrency for C: Tokio + Seastar + BEAM, in one library
Loading...
Searching...
No Matches
xtc_preempt_involuntary.h
1
/*-
2
* Copyright (c) 2026, The XTC Project -- All rights reserved.
3
* @stability experimental
4
* Use of this source code is governed by the ISC License.
5
*
6
* src/inc/xtc_preempt_involuntary.h
7
* Involuntary (signal-context) preemption: a timer tick that lands
8
* in a running fiber yields it to the scheduler at the interrupted
9
* instruction, so a loop-mate runs even while the fiber never reaches
10
* a yield point. EXPERIMENTAL (docs/abi-stability.md): the contract
11
* below may change in any minor release. The timer itself, and
12
* cooperative-assisted preemption, are in "xtc_preempt.h" (stable).
13
*
14
* THE CONTRACT (xtc_preempt_involuntary(3)):
15
* - A tick yields the fiber only at a SAFE POINT: outside a
16
* critical section and libxtc's own internal regions, and at a PC
17
* inside a PREEMPTIBLE range: every function marked
18
* XTC_PREEMPTIBLE, ranges added with xtc_preempt_region_add, and
19
* the main executable's own code when libxtc and libc are both
20
* shared objects. A static libxtc or libc lies inside the main
21
* text and cannot be told apart from it, so a STATIC BUILD MUST
22
* MARK ITS PREEMPTIBLE CODE (enabling with none fails). Never libc, other shared libraries, or
23
* libxtc itself: code compiled for a thread (malloc's per-thread
24
* cache, a FILE's per-thread lock) is not safe to interleave with a
25
* loop-mate on the same thread. Elsewhere the tick stays pending
26
* and the fiber yields at its next yield point.
27
* - The interrupted code resumes with its whole register file,
28
* flags, vector state, x87 state, PKRU and errno. The scheduler
29
* and the fibers it runs in the slice start from a call-boundary
30
* state (DF/AC clear, empty x87 stack, clean AVX upper halves; SME
31
* streaming mode and ZA off on aarch64).
32
* - Code in a preemptible range must not hold per-thread state a
33
* loop-mate could disturb (a thread-local scratch buffer, a lock
34
* that a loop-mate also takes) across instructions without a
35
* critical section (xtc_proc_critical_enter / _leave).
36
* - Linux x86-64 (ucontext; fcontext with glibc) and Linux aarch64
37
* only: xtc_preempt_involuntary_supported() says which. CET
38
* shadow stacks, AMX tile state and the aarch64 guarded control
39
* stack are not supported.
40
*/
41
42
#ifndef XTC_PREEMPT_INVOLUNTARY_H
43
#define XTC_PREEMPT_INVOLUNTARY_H
44
45
#include "xtc_export.h"
46
47
#include "xtc.h"
48
49
/*
50
* Mark a function preemptible: it is placed in the xtc_preemptible
51
* section, which the safe-point check trusts even in a static build
52
* (where the main text holds libxtc or libc and is not trusted). A marked function must follow the contract above; it may
53
* call anything, but a tick that lands in a callee outside a preemptible
54
* range is deferred. ELF with GCC or Clang; empty elsewhere.
55
*/
56
#if defined(__ELF__) && (defined(__GNUC__) || defined(__clang__))
57
# define XTC_PREEMPTIBLE \
58
__attribute__((section("xtc_preemptible"), noinline))
59
#else
60
# define XTC_PREEMPTIBLE
61
#endif
62
63
/*
64
* PUBLIC: int xtc_preempt_set_involuntary __P((int));
65
* PUBLIC: int xtc_preempt_involuntary_supported __P((void));
66
* PUBLIC: int xtc_preempt_region_add __P((const void *, const void *));
67
*/
68
69
/* Enable (on != 0) or disable involuntary preemption, process-wide. It
70
* acts on threads whose preemption timer is armed (xtc_preempt_arm,
71
* xtc_exec_set_preempt). Off by default. Returns XTC_OK; enabling
72
* returns XTC_E_NOSYS, and leaves it off, where
73
* xtc_preempt_involuntary_supported() is 0 or no preemptible range can
74
* be trusted (a static executable with no XTC_PREEMPTIBLE function and
75
* no region added; adding one later lifts that refusal); the reason is
76
* reported once, at XTC_LOG_ERROR and on stderr. */
77
XTC_API
int
xtc_preempt_set_involuntary(
int
on);
78
79
/* 1 if this build and platform implement the involuntary redirect
80
* (Linux x86-64 on ucontext or glibc fcontext; Linux aarch64), else 0. */
81
XTC_API
int
xtc_preempt_involuntary_supported(
void
);
82
83
/* Add [start, end) to the preemptible ranges (code the application
84
* vouches for, e.g. a JIT buffer or a static build's own objects). Call
85
* before enabling. XTC_E_INVAL for an empty range or one overlapping
86
* libxtc's own text; XTC_E_RESOURCE when the table (32 ranges) is full.
87
* Ranges cannot be removed. */
88
XTC_API
int
xtc_preempt_region_add(
const
void
*start,
const
void
*end);
89
90
#endif
/* XTC_PREEMPT_INVOLUNTARY_H */
src
inc
xtc_preempt_involuntary.h
Generated by
1.9.8