libxtc 0.4.0
Async concurrency for C: Tokio + Seastar + BEAM, in one library
Loading...
Searching...
No Matches
xtc_exec.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_exec.h
6 * The L2 multi-loop executor. Owns N xtc_loop instances, each
7 * running on its own OS thread. Tasks may be spawned on any loop
8 * from any thread; cross-thread wakers go through a per-loop MPSC
9 * inbox + xtc_io_wakeup pingback.
10 *
11 * See M5_CLAIMS.md.
12 */
13
14#ifndef XTC_EXEC_H
15#define XTC_EXEC_H
16
17#include <stdint.h>
18
19#include "xtc_loop.h"
20#include "xtc_async.h"
21
22typedef struct xtc_exec xtc_exec_t;
23
24/*
25 * PUBLIC: int xtc_exec_init __P((xtc_exec_t **, int));
26 * PUBLIC: int xtc_exec_fini __P((xtc_exec_t *));
27 * PUBLIC: int xtc_exec_run __P((xtc_exec_t *));
28 * PUBLIC: void xtc_exec_set_service_mode __P((xtc_exec_t *, int));
29 * PUBLIC: int xtc_exec_stop __P((xtc_exec_t *));
30 * PUBLIC: int xtc_exec_n_loops __P((xtc_exec_t *));
31 * PUBLIC: int xtc_exec_loop_id __P((void));
32 * PUBLIC: int xtc_shard_id __P((void));
33 * PUBLIC: int xtc_shard_count __P((void));
34 * PUBLIC: xtc_loop_t *xtc_exec_loop __P((xtc_exec_t *, int));
35 *
36 * PUBLIC: int xtc_exec_spawn __P((xtc_exec_t *, xtc_task_fn, void *, xtc_task_t **));
37 * PUBLIC: int xtc_exec_spawn_on __P((xtc_exec_t *, int, xtc_task_fn, void *, xtc_task_t **));
38 * PUBLIC: int xtc_exec_async __P((xtc_exec_t *, xtc_coro_fn, void *, xtc_task_t **));
39 * PUBLIC: int xtc_exec_async_on __P((xtc_exec_t *, int, xtc_coro_fn, void *, xtc_task_t **));
40 */
41
42/*
43 * Lifecycle. n_loops <= 0 selects __os_ncpus().
44 *
45 * `xtc_exec_run` blocks the calling thread until the executor stops:
46 * - all spawned tasks DONE and all timers fired/cancelled, or
47 * - xtc_exec_stop() called from any thread.
48 *
49 * On return all worker threads have been joined.
50 */
51int xtc_exec_init(xtc_exec_t **out, int n_loops);
52int xtc_exec_fini(xtc_exec_t *exec);
53int xtc_exec_run(xtc_exec_t *exec);
54
55/* Service mode: when set, xtc_exec_run does not idle-auto-stop and runs
56 * until xtc_exec_stop is called. Used by a supervised xtc_app, which is
57 * a long-running service rather than a finite work pool. */
58void xtc_exec_set_service_mode(xtc_exec_t *exec, int on);
59int xtc_exec_set_preempt(xtc_exec_t *exec, int64_t interval_ns);
60int xtc_exec_stop(xtc_exec_t *exec);
61
62int xtc_exec_n_loops(xtc_exec_t *exec);
63
64/*
65 * From inside a task running on a loop, returns that loop's
66 * 0-based index. From any other thread returns -1. Tests use this
67 * to verify cross-loop spawn placement and steals.
68 */
69int xtc_exec_loop_id(void);
70
71/* Seastar-style per-shard API. xtc_shard_id() is the 0-based index of
72 * the loop the caller runs on (a standalone loop is shard 0 of 1; -1
73 * off a loop); xtc_shard_count() is the number of shards (1 for a
74 * standalone loop, 0 off a loop). Index per-core state with these
75 * for a shared-nothing design. */
76int xtc_shard_id(void);
77int xtc_shard_count(void);
78
79/* Borrow a loop pointer (for tests; not generally needed). */
80xtc_loop_t *xtc_exec_loop(xtc_exec_t *exec, int idx);
81
82/*
83 * Per-loop work statistics, for observability and load-balance
84 * diagnosis (e.g. confirming work stealing is distributing under a
85 * tail-latency-sensitive workload).
86 *
87 * tasks_run -- task steps executed on this loop
88 * steals -- tasks this loop successfully stole from a peer
89 *
90 * Reads are lock-free snapshots of relaxed atomics; exactness across
91 * a concurrently running executor is not guaranteed.
92 */
93typedef struct xtc_loop_stats {
94 uint64_t tasks_run;
95 uint64_t steals;
97
98/*
99 * PUBLIC: int xtc_exec_loop_stats __P((xtc_exec_t *, int, xtc_loop_stats_t *));
100 */
101int xtc_exec_loop_stats(xtc_exec_t *exec, int idx, xtc_loop_stats_t *out);
102
103/*
104 * Spawns. These are the multi-loop equivalents of xtc_task_spawn /
105 * xtc_async; they may be called from any thread.
106 */
107int xtc_exec_spawn(xtc_exec_t *exec, xtc_task_fn fn, void *user,
108 xtc_task_t **out_task);
109int xtc_exec_spawn_on(xtc_exec_t *exec, int loop_idx,
110 xtc_task_fn fn, void *user, xtc_task_t **out_task);
111int xtc_exec_async(xtc_exec_t *exec, xtc_coro_fn fn, void *arg,
112 xtc_task_t **out_task);
113int xtc_exec_async_on(xtc_exec_t *exec, int loop_idx,
114 xtc_coro_fn fn, void *arg, xtc_task_t **out_task);
115
116#endif /* XTC_EXEC_H */