libxtc 0.4.0
Async concurrency for C: Tokio + Seastar + BEAM, in one library
Loading...
Searching...
No Matches
xtc_rcu.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_rcu.h
6 * Read-Copy-Update epoch reclamation. Wait-free readers,
7 * deferred-reclaim writers. This is the foundation that
8 * xtc_lrlock (M13b) and xtc_chash (M11.5) build on.
9 *
10 * Model:
11 * - A global epoch counter advances on each "grace period".
12 * - Each thread records the epoch it entered a read-side
13 * critical section.
14 * - To free an object, a writer hands it to xtc_rcu_retire;
15 * the object is held until every thread has either left its
16 * read-side or moved to a strictly newer epoch.
17 *
18 * This first cut uses a single global epoch + a per-thread slot
19 * registered lazily. A periodic helper (or any writer's call to
20 * xtc_rcu_synchronize) advances the epoch. M13a-rev2 will ship
21 * a per-NUMA-node bucketing for scaling.
22 */
23
24#ifndef XTC_RCU_H
25#define XTC_RCU_H
26
27#include "xtc_export.h"
28
29#include <stddef.h>
30#include <stdint.h>
31
32#include "xtc.h"
33
34typedef void (*xtc_rcu_free_fn)(void *p);
35
36/*
37 * PUBLIC: int xtc_rcu_init __P((void));
38 * PUBLIC: void xtc_rcu_fini __P((void));
39 *
40 * PUBLIC: void xtc_rcu_read_lock __P((void));
41 * PUBLIC: void xtc_rcu_read_unlock __P((void));
42 *
43 * PUBLIC: void xtc_rcu_retire __P((void *, xtc_rcu_free_fn));
44 * PUBLIC: void xtc_rcu_synchronize __P((void));
45 *
46 * PUBLIC: uint64_t xtc_rcu_current_epoch __P((void));
47 */
48
49/* Initialise the RCU subsystem. Idempotent. Called automatically by
50 * the first read_lock or retire; explicit init lets callers fail
51 * early if storage allocation fails. */
52XTC_API int xtc_rcu_init(void);
53
54/* Finalise: drain all pending callbacks and free per-thread state.
55 * Safe to call only when no readers are active. */
56XTC_API void xtc_rcu_fini(void);
57
58/* Mark the start / end of a read-side critical section. Reads
59 * between lock and unlock see a consistent snapshot of any
60 * RCU-protected pointer that was loaded after the lock.
61 *
62 * Lock/unlock are nestable on the same thread (refcount-style).
63 * No system call, no atomic compare-exchange on the fast path. */
64XTC_API void xtc_rcu_read_lock(void);
65XTC_API void xtc_rcu_read_unlock(void);
66
67/* Schedule `p` to be freed (via fn(p)) after every reader currently
68 * inside a read-side has finished. The actual free happens lazily
69 * on the next epoch advance + a writer's synchronize call. */
70XTC_API void xtc_rcu_retire(void *p, xtc_rcu_free_fn fn);
71
72/* Advance the global epoch and reclaim everything that's now safe.
73 * Safe to call from any thread. Blocks briefly while waiting for
74 * readers in the previous epoch to drain. */
75XTC_API void xtc_rcu_synchronize(void);
76
77XTC_API uint64_t xtc_rcu_current_epoch(void);
78
79#endif /* XTC_RCU_H */