libxtc 0.4.0
Async concurrency for C: Tokio + Seastar + BEAM, in one library
Loading...
Searching...
No Matches
preempt_int.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/preempt_int.h
6 * Internal preemption primitives -- the __xtc_* async-signal-unsafe
7 * bracket and the preemption-safe raw-pthread mutex wrappers.
8 *
9 * These are library-internal (the __ prefix): they are used across
10 * the runtime (the allocator, latches, every subsystem embedding a
11 * bare pthread_mutex_t) but are NOT part of the consumer-facing API,
12 * so they live here rather than in the installed xtc_preempt.h. A
13 * library source that needs them includes this header; a consumer
14 * never sees them. (Split out of xtc_preempt.h so no __-prefixed
15 * symbol leaks into an installed public header.)
16 */
17
18#ifndef XTC_PREEMPT_INT_H
19#define XTC_PREEMPT_INT_H
20
21#include "xtc_export.h"
22
23#include <pthread.h>
24
25/*
26 * Async-signal-unsafe-region depth (Phase 2 prerequisite). A per-thread
27 * nesting counter that is > 0 while the thread is inside an
28 * async-signal-unsafe region (the allocator, a latch's internal lock).
29 * The preemption timer handler must not do a signal-context involuntary
30 * yield while it is > 0 (it defers). __xtc_unsafe_enter/leave bracket
31 * such a region; __xtc_unsafe_depth reads the current depth (also used
32 * by the fault handler so a SIGSEGV inside malloc does not unwind out of
33 * a corrupt arena).
34 *
35 * PUBLIC: void __xtc_unsafe_enter __P((void));
36 * PUBLIC: void __xtc_unsafe_leave __P((void));
37 * PUBLIC: int __xtc_unsafe_depth __P((void));
38 */
39XTC_API void __xtc_unsafe_enter(void);
40XTC_API void __xtc_unsafe_leave(void);
41XTC_API int __xtc_unsafe_depth(void);
42
43/*
44 * Preemption-safe raw-pthread mutex brackets. A fiber that holds a
45 * mutex must not be involuntarily preempted (a loop runs many fibers on
46 * one OS thread; a preempted holder plus another same-loop fiber
47 * blocking on the same mutex deadlocks the thread). __xtc_mtx_lock/
48 * unlock wrap pthread_mutex_lock/unlock with __xtc_unsafe_enter/leave
49 * so the preemption timer defers while the lock is held -- the
50 * raw-pthread counterpart of the preemption-safe __os_mutex_* locks,
51 * for internal subsystems that embed a bare pthread_mutex_t. Use only
52 * for short critical sections that do NOT yield/park while holding the
53 * lock. They return the raw pthread errno (0 == success).
54 */
55int __xtc_mtx_lock(pthread_mutex_t *m);
56int __xtc_mtx_unlock(pthread_mutex_t *m);
57
58/*
59 * 1 if signal-context involuntary yield (Phase 2) is enabled. Internal
60 * accessor for the io_uring executor path: the ring-pointer preempt
61 * source (L2) drives the cooperative yield-check with no signal, but
62 * Phase 2 (redirecting a fiber that never reaches a yield-check) needs
63 * the SIGVTALRM/kqueue timer, so exec.c keeps the timer armed when this
64 * is on.
65 */
66XTC_API int __xtc_preempt_involuntary_enabled(void);
67
68#endif /* XTC_PREEMPT_INT_H */