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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
pub use Duration;
use ;
pub use crateInstant;
use crateTimeoutError;
// Functional references (`sleep`/`timeout` below, `crate::thread::park_timeout`
// in `virtual_park_timeout`) deliberately stay on the lane-gated root glob:
// the inert `virtual_*` aliases ARE whichever backend owns the lane (native or
// wasm), so they must resolve through it. Typed imports above come from
// `common::time` directly (the backends re-export the same types). The glob
// dependency is a known wart; it dies with the W3/W5 layering work.
use crate;
/// Off the sim path a spawned task needs no quiescence accounting, so the
/// participant wrapper is the future itself. Under `flash` this is the
/// engine's gate wrapper counted in `active_async`.
pub type Participating<F> = F;
/// Off the sim path: spawning needs no quiescence bracket, so `participate` is
/// an identity passthrough (the real clock already advances on its own). Under
/// `flash` this is the engine's `participate`, which wraps the future so it
/// counts in the engine's `active_async` while running. The `loc` spawn-site
/// identity (used by the engine's hang dump) is unused off the sim path.
/// Off the sim path ambient does not exist, so there is nothing to re-assert
/// per poll: the wrapper is the future itself. Under `flash` this is the
/// engine's per-poll ambient re-assert wrapper.
pub type WithAmbient<F> = F;
/// Off the sim path: ambient does not exist, so re-asserting it per poll is an
/// identity passthrough. Under `flash` this is the engine's `with_ambient`,
/// which re-establishes the snapshotted ambient around every poll so a future
/// (e.g. the async test body) keeps its flash-eligibility across `.await`
/// thread-hops instead of relying on a one-shot guard set on the first poll.
/// No-op real-time scope off the sim path (time is already real). `!Send`
/// (`PhantomData<*mut ()>`) for auto-trait PARITY with the engine guard: a
/// consumer compiling against the inert form must not become Send-legal code
/// that fails to compile under `flash`.
/// Enter a real-time scope. Off the sim path this is a ZST no-op; under
/// `flash` it puts the current thread on real time for the guard's lifetime.
/// Off the sim path: a prod `#[kithara::flash(bool)]` sync region's RAII guard is
/// a ZST no-op (time is already real), so an annotated fn compiles away to its
/// bare body. Under `flash` this is the engine's `enter_dynamic`.
/// Off the sim path a prod async `#[kithara::flash(bool)]` region needs no
/// per-poll mode re-assert: the wrapper is the future itself. Under `flash`
/// this is the engine's per-poll dynamic-flash wrapper.
pub type FlashDynamic<F> = F;
/// Off the sim path: a prod `#[kithara::flash(bool)]` async region is an identity
/// passthrough (no per-poll re-assert needed when time is already real). Under
/// `flash` this is the engine's `dynamic`.
/// Inert mirror of the engine-backed yield future. Never produced by the inert
/// [`yield_now`] (off the sim path the real arm is always taken); present so
/// the surface matches the flash control surface 1:1.
/// Cooperative async yield. Off the sim path this always takes the real arm —
/// the same semantics the engine build uses outside a flash-eligible test:
/// hand control back to the scheduler once, then resolve.
/// Cooperative yield future (see [`yield_now`]). Mirrors the flash enum; the
/// [`Yield::Flash`] variant is never constructed off the sim path.
/// Off the sim path the lexical test rewriter's `virtual_*` targets alias
/// the REAL primitives, so a rewritten test body behaves identically to its
/// unrewritten form (the rewrite is a no-op when `flash` is off). The
/// `#[kithara::test]` macro emits these into EVERY test body, so they must
/// resolve in the off-feature + wasm configs.
/// Off-feature real alias for the rewriter's virtual `timeout` (see
/// [`virtual_sleep`]).
///
/// # Errors
///
/// Returns [`TimeoutError`] if the future does not complete within `duration`.
pub async
/// Off-feature real alias for the rewriter's virtual `Instant::now` (see
/// [`virtual_sleep`]).
/// Off-feature real alias for the rewriter's virtual `park_timeout` (see
/// [`virtual_sleep`]).
/// No virtual timeline or quiescence engine to reset off the sim path (the
/// clock is real), so this is a no-op.
/// Off the sim path a real I/O operation needs no pacing (time is already
/// real), so the scope is a ZST no-op. Under `flash` it is the engine's
/// `RealIoScope`: while held, the virtual clock may not outrun real
/// time, so virtual watchdogs/timeouts cannot fire spuriously ahead of bytes
/// still on the wire.
;
/// Bracket ONE real I/O operation. Off the sim path this is a ZST no-op;
/// under `flash` it paces the virtual clock to real time while held.
/// No-op per-test ambient gate off the sim path (time is already real). The
/// `#[kithara::test]` macro emits `ambient_scope(..)` into sync and wasm test
/// bodies (async-native bodies carry `with_ambient` per-poll instead), so the
/// guard must exist (as a ZST) in the off-feature + wasm configs. Under
/// `flash` this is the engine's `AmbientScope` / `ambient_scope`. `!Send` for
/// auto-trait parity with the engine guard (see [`FlashScope`]).
/// Set the per-test ambient gate. Off the sim path this is a ZST no-op (time is
/// already real); under `flash` it is the engine's `ambient_scope`.
/// Snapshot the per-test ambient gate for spawn propagation. Off the sim path
/// the gate does not exist and no test is flash-eligible, so the snapshot is
/// always `false` (the engine's default outside a flash test).
/// Restore a snapshotted ambient on a spawned child. Off the sim path this is
/// the ZST no-op guard (see [`ambient_scope`]); under `flash` it re-establishes
/// the engine's per-test gate for the child's lifetime.
/// No engine to report without the `flash` feature (or on wasm).
/// No engine to report without the `flash` feature (or on wasm).