libxtc 0.4.0
Async concurrency for C: Tokio + Seastar + BEAM, in one library
Loading...
Searching...
No Matches
coro_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/coro_int.h
6 * Internal types for the L2 coroutine substrate.
7 */
8
9#ifndef XTC_CORO_INT_H
10#define XTC_CORO_INT_H
11
12#if defined(_WIN32)
13# include <windows.h>
14#elif defined(XTC_HAVE_UCONTEXT) && !defined(XTC_CORO_FORCE_FCTX)
15# include <ucontext.h>
16#endif
17
18#include "xtc_async.h"
19#include "loop_int.h"
20
21/*
22 * The fiber context attached to an xtc_task_t when it was spawned
23 * via xtc_async. Lives in the per-task arena (currently malloc).
24 */
25struct xtc_coro {
26#if defined(_WIN32)
27 LPVOID fiber; /* the coroutine's own Win32 fiber */
28 LPVOID loop_fiber; /* return-to-loop fiber pointer */
29#elif defined(XTC_HAVE_UCONTEXT) && !defined(XTC_CORO_FORCE_FCTX)
30 ucontext_t ctx; /* the coroutine's own machine state */
31 ucontext_t loop_ctx; /* return-to-loop context (set on resume) */
32#else
33 /* fcontext substrate (coro_fctx.c): a single saved stack pointer.
34 * On make_fcontext it is the fresh entry point; each yield/await
35 * overwrites it with the coroutine's current resume point. The
36 * scheduler's return point is a per-thread cursor in coro_fctx.c,
37 * not stored here, because coroutines always return to the
38 * scheduler, never directly to one another. */
39 void *fctx;
40#endif
41 void *stack;
42 size_t stack_sz;
43 xtc_coro_fn fn;
44 void *arg;
45 intptr_t result;
46 int done; /* 1 once fn has returned */
47
48 xtc_task_t *self; /* back-pointer to our task */
49 xtc_task_t *waiter; /* task awaiting this one (or NULL) */
50
51 /*
52 * When non-NULL, this coroutine has just registered itself as
53 * the `waiter` of another and is yielding into the loop with
54 * the intent of staying parked rather than rescheduling. The
55 * step function reads and clears this flag to decide between
56 * RESCHED and PENDING.
57 */
58 struct xtc_coro *_parked_on;
59
60 /*
61 * Sanitizer fiber-switch save token (ASan/TSan/LSan). Holds this
62 * coro's "fake stack" across a park so __sanitizer_start/finish_
63 * switch_fiber can track the user-space stack switch and stop
64 * mis-attributing stack memory. Unused (always NULL) in a
65 * non-sanitized build. See XTC_FIBER_SWITCH_ANNOTATE in
66 * coro_fctx.c / coro_uctx.c.
67 */
68 void *san_fake_stack;
69
70 /*
71 * TSan fiber-IDENTITY token (clang ThreadSanitizer only). TSan
72 * does NOT implement __sanitizer_*_switch_fiber; it needs each
73 * coroutine represented as a TSan "fiber object" (__tsan_create_
74 * fiber at create, __tsan_switch_to_fiber at every switch,
75 * __tsan_destroy_fiber at teardown) so it can carry per-fiber
76 * happens-before across cooperative switches instead of seeing
77 * them as one confused thread. Distinct from san_fake_stack (the
78 * two sanitizer models are mutually exclusive per build). Always
79 * NULL unless built with clang -fsanitize=thread. See
80 * XTC_TSAN_FIBERS in coro_fctx.c / coro_uctx.c.
81 */
82 void *tsan_fiber;
83};
84
85/* Shared by loop.c -- the currently-running coroutine on this loop. */
86extern XTC_THREAD_LOCAL struct xtc_coro *__xtc_current_coro;
87
88/* Forward declarations for the dispatch glue. */
89int __xtc_coro_step(xtc_task_t *self, void *user);
90
91/* The task wrapping the currently-running coroutine on this thread,
92 * or NULL when not running inside a coroutine. Lets lower-level
93 * primitives (e.g. xtc_amutex) find the current task to park it. */
94xtc_task_t *__xtc_current_task(void);
95
96#endif /* XTC_CORO_INT_H */