1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
//! # light-qsbr
//!
//! `light-qsbr` provides a **lightweight Quiescent-State-Based Reclamation (QSBR)**
//! mechanism for asynchronous runtimes and lock-free data structures.
//!
//! It is designed as a minimal alternative to heavy garbage collectors and allows
//! safe memory reclamation in concurrent environments, where objects can only be freed
//! once all participating threads have advanced past a known **epoch**.
//!
//! ## Core Concepts
//!
//! - [`SharedManager`] is the **global manager**.
//! It tracks the current global epoch and the number of executors participating in each epoch.
//!
//! - [`LocalManager`] is the **thread-local manager**.
//! Each executor (thread or runtime worker) has its own local manager,
//! which schedules memory to be deallocated or dropped when it is safe.
//!
//! - **Epochs** are global counters.
//! Memory is only reclaimed once all executors have passed the epoch
//! in which the memory was retired.
//!
//! ## Workflow
//!
//! 1. Create a [`SharedManager`].
//! 2. For each executor (thread/worker), call [`SharedManager::register_new_executor`].
//! This installs a thread-local [`LocalManager`].
//! 3. Executors schedule memory for deallocation or dropping via
//! [`LocalManager::schedule_deallocate`], [`LocalManager::schedule_deallocate_slice`],
//! or [`LocalManager::schedule_drop`].
//! 4. Periodically, executors call [`LocalManager::maybe_pass_epoch`] to attempt to advance
//! the epoch and trigger safe reclamation.
//! 5. When shutting down, executors must call
//! `unsafe { LocalManager::deregister() }` to deregister themselves.
//!
//! ## Example
//!
//! ```rust
//! use std::cell::Cell;
//! use light_qsbr::{SharedManager, local_manager, LocalManager};
//! use light_qsbr::orengine_utils::OrengineInstant;
//!
//! # fn main() {
//! let shared = SharedManager::new();
//!
//! // Register an executor for this thread
//! shared.register_new_executor();
//!
//! // Schedule deallocation or dropping through the local manager
//! let value = Box::new(42);
//! let ptr = Box::into_raw(value);
//! unsafe {
//! local_manager().schedule_deallocate(ptr);
//! }
//!
//! // Periodically try to advance the epoch (e.g., in an event loop)
//! local_manager().maybe_pass_epoch(OrengineInstant::now());
//!
//! // Deregister before thread exit
//! unsafe { LocalManager::deregister() };
//! # }
//! ```
//!
//! ## Safety Guarantees
//!
//! - Objects scheduled for reclamation will only be freed once **all executors**
//! have passed the epoch in which they were retired.
//! - The API is intentionally minimal: the runtime must periodically call
//! [`LocalManager::maybe_pass_epoch`] to make progress.
//!
//! ## When to Use
//!
//! - Implementing lock-free collections that need safe memory reclamation.
//! - Async runtimes that want QSBR without the overhead of hazard pointers or full garbage collection.
//! - Situations where *you control executor lifecycle* and can ensure correct registration/deregistration.
//!
//! ## When *Not* to Use
//!
//! - If you need automatic reclamation without explicit epoch-passing.
//! - If your workload is highly dynamic with frequent thread churn—QSBR works best with stable executor sets.
//!
//! ## See Also
//!
//! - [`SharedManager`] for the global epoch tracker.
//! - [`LocalManager`] for per-thread scheduling of reclamation.
//! - [`local_manager`] to access the thread-local [`LocalManager`].
//!
//! ---
pub use orengine_utils;
pub use *;
pub use *;