libxtc 0.4.0
Async concurrency for C: Tokio + Seastar + BEAM, in one library
Loading...
Searching...
No Matches
xtc.h
1/*-
2 * Copyright (c) 2026, The XTC Project
3 *
4 * Use of this source code is governed by the ISC License,
5 * a copy of which is in the file LICENSE in the top-level directory
6 * of this distribution.
7 *
8 * src/inc/xtc.h
9 * The single public header for the xtc library.
10 * See M0_CLAIMS.md [C4]: including this header alone is sufficient
11 * to use every M0-public API.
12 */
13
14#ifndef XTC_H
15#define XTC_H
16
17#ifdef __cplusplus
18extern "C" {
19#endif
20
21#include <stddef.h>
22#include <stdint.h> /* int64_t for the public clock / atomic helpers */
23
24/*
25 * Compile-time version macros.
26 * These values come from configure-time substitution into xtc_config.h
27 * via the build system; if xtc_config.h is unavailable (rare; e.g. when
28 * a consumer parses just this header), they fall back to known-bad
29 * sentinels so a missing build is detected loudly.
30 */
31#if defined(__has_include)
32# if __has_include("xtc_config.h")
33# include "xtc_config.h"
34# endif
35#endif
36
37#ifndef XTC_VERSION_MAJOR
38# define XTC_VERSION_MAJOR 0
39#endif
40#ifndef XTC_VERSION_MINOR
41# define XTC_VERSION_MINOR 0
42#endif
43#ifndef XTC_VERSION_PATCH
44# define XTC_VERSION_PATCH 0
45#endif
46#ifndef XTC_VERSION_STRING
47# define XTC_VERSION_STRING "0.0.0-unconfigured"
48#endif
49
50/*
51 * Error codes.
52 * 0 == OK; negative values are stable XTC_E_* codes.
53 * Codes are added at the end of the enumeration in minor releases and
54 * never renumbered. See docs/abi-stability.md.
55 */
56typedef enum xtc_err {
57 XTC_OK = 0, /* success */
58 XTC_E_INVAL = -1, /* invalid argument */
59 XTC_E_NOMEM = -2, /* out of memory */
60 XTC_E_NOSYS = -3, /* not implemented on this platform */
61 XTC_E_RANGE = -4, /* numeric out of range */
62 XTC_E_AGAIN = -5, /* try again later */
63 XTC_E_INTERNAL = -6, /* invariant violation; bug */
64 XTC_E_RESOURCE = -7, /* resource cap reached (xtc_res) */
65 XTC_E_DEADLK = -8, /* lock-manager: deadlock victim */
66 XTC_E_VERSION = -9, /* version mismatch (shm) */
67 XTC_E_ABORTED = -10, /* operation cancelled via abort token */
68 XTC_E_NOTFOUND = -11, /* requested item does not exist */
69 XTC_E_IO = -12 /* I/O error (read/write/fsync failed) */
70} xtc_err_t;
71
72/*
73 * xtc_version_string --
74 * Return the library version as a NUL-terminated SemVer 2.0 string.
75 * The pointer is to static storage; the caller must not free it.
76 * See M0_CLAIMS.md [C1].
77 */
78const char *xtc_version_string(void);
79
80/*
81 * xtc_version_components --
82 * Decompose the version into three integers.
83 * On success returns XTC_OK and writes *major, *minor, *patch.
84 * On NULL out-pointers returns XTC_E_INVAL.
85 * See M0_CLAIMS.md [C2].
86 */
87int xtc_version_components(int *major, int *minor, int *patch);
88
89/*
90 * xtc_strerror --
91 * Return a stable English description of an xtc error code.
92 * The pointer is to static storage; the caller must not free it.
93 * Returns a pointer to "unknown" for codes outside the known set
94 * rather than NULL, so callers can chain into log lines safely.
95 * See M0_CLAIMS.md [C6].
96 */
97const char *xtc_strerror(int xtc_err);
98
99/*
100 * xtc_free --
101 * Free a heap buffer that a libxtc call handed to the caller to own
102 * -- notably the message buffer from xtc_recv / xtc_recv_match /
103 * xtc_recv_correlate, the frame from xtc_net_recv_frame, the reply
104 * from xtc_osproc_call / xtc_svr_call, and any other buffer whose
105 * documentation says "free with xtc_free". Those buffers are
106 * allocated by libxtc's own allocator, which is not necessarily the
107 * C library malloc/free, so they MUST be released through this
108 * function rather than plain free(). Passing NULL is a no-op.
109 *
110 * This is the public name for the library allocator's deallocation
111 * entry point; it is safe to call from any thread.
112 */
113void xtc_free(void *p);
114
115/*
116 * xtc_malloc / xtc_calloc / xtc_realloc --
117 * Allocate through libxtc's own allocator (the same one xtc_free
118 * releases and that xtc_alloc_set_hook can override), so a consumer
119 * never needs the internal __os_* surface. Return the pointer
120 * directly (NULL on failure), matching the C idiom; the result is
121 * released with xtc_free. xtc_calloc zero-fills; xtc_realloc grows
122 * / shrinks an xtc_malloc/xtc_calloc/xtc_realloc block (NULL p acts
123 * like xtc_malloc). A zero size yields a unique freeable pointer,
124 * not NULL. Safe from any thread. These are the public complement
125 * to xtc_free -- library CONSUMERS use only the xtc_* API, never the
126 * internal __os_* wrappers.
127 */
128void *xtc_malloc(size_t size);
129void *xtc_calloc(size_t n, size_t size);
130void *xtc_realloc(void *p, size_t size);
131
132/*
133 * xtc_aligned_alloc / xtc_aligned_free --
134 * Allocate `size` bytes aligned to `align` (a power of two, e.g.
135 * XTC_CACHE_LINE) through libxtc's allocator; release ONLY with
136 * xtc_aligned_free (never xtc_free -- an aligned block may carry
137 * header/padding a plain free would mishandle). Returns NULL on
138 * failure. For a struct with an over-aligned member.
139 */
140void *xtc_aligned_alloc(size_t align, size_t size);
141void xtc_aligned_free(void *p);
142
143/*
144 * xtc_clock_mono / xtc_clock_real --
145 * Read the monotonic (never goes backward; for intervals/timeouts)
146 * or real (wall-clock; for timestamps) clock in NANOSECONDS. Return
147 * the time directly (0 on the rare query failure). These are the
148 * public clocks a consumer uses instead of raw clock_gettime.
149 */
150int64_t xtc_clock_mono(void);
151int64_t xtc_clock_real(void);
152
153/*
154 * xtc_sleep_ns --
155 * Sleep the CALLING OS THREAD for at least `ns` nanoseconds. This
156 * is a THREAD sleep (blocking); inside a fiber use xtc_proc_sleep
157 * instead, which parks the fiber and keeps the loop live. Provided
158 * so a consumer never needs raw nanosleep. Returns XTC_OK, or a
159 * negative XTC_E_* on interruption/error.
160 */
161int xtc_sleep_ns(int64_t ns);
162
163/*
164 * xtc_atomic_i64_load / xtc_atomic_i64_add --
165 * Relaxed atomic load, and atomic fetch-add (returns the PRIOR
166 * value), on a shared int64_t. The minimal public atomic surface a
167 * consumer needs for a shared counter / token bucket without reaching
168 * for the internal __os_atomic_* macros or a compiler builtin.
169 */
170int64_t xtc_atomic_i64_load(const int64_t *p);
171int64_t xtc_atomic_i64_add(int64_t *p, int64_t delta);
172
173#ifdef __cplusplus
174}
175#endif
176
177#endif /* XTC_H */