mnemosyne_local/
selector.rs1#[macro_export]
6macro_rules! impl_local_allocator_selector {
7 ($backend:ty) => {
8 const _: () = {
9 #[cfg(nightly_tls_active)]
11 #[thread_local]
12 static ALLOCATOR_SLOT: $crate::LocalAllocatorSlot<$backend> =
13 $crate::LocalAllocatorSlot::new();
14
15 #[cfg(not(nightly_tls_active))]
17 std::thread_local! {
18 static ALLOCATOR_SLOT: $crate::LocalAllocatorSlot<$backend> = const {
19 $crate::LocalAllocatorSlot::new()
20 };
21 }
22
23 std::thread_local! {
25 static CACHED_SLOT_PTR: core::cell::Cell<*mut core::ffi::c_void> = const {
26 core::cell::Cell::new(core::ptr::null_mut())
27 };
28
29 #[cfg(nightly_tls_active)]
30 static ALLOCATOR_EXIT_GUARD: $crate::ThreadExitReclaim<$backend> = const {
31 $crate::ThreadExitReclaim::new()
32 };
33 }
34
35 #[cfg(nightly_tls_active)]
36 #[thread_local]
37 static mut QUICK_ALLOCATOR_PTR: *mut core::ffi::c_void = core::ptr::null_mut();
38
39 static OS_TLS_KEY: core::sync::atomic::AtomicU32 = core::sync::atomic::AtomicU32::new(u32::MAX);
40
41 struct SlotAccess;
42 impl $crate::tls::TlsSlotAccess<$backend> for SlotAccess {
43 #[inline(always)]
44 fn get_slot_standard<R>(f: impl FnOnce(&$crate::LocalAllocatorSlot<$backend>) -> R) -> R {
45 #[cfg(nightly_tls_active)]
46 {
47 f(&ALLOCATOR_SLOT)
49 }
50 #[cfg(not(nightly_tls_active))]
51 {
52 ALLOCATOR_SLOT.with(f)
53 }
54 }
55
56 #[inline(always)]
57 fn get_cached_cell<R>(f: impl FnOnce(&core::cell::Cell<*mut core::ffi::c_void>) -> R) -> R {
58 CACHED_SLOT_PTR.with(f)
59 }
60
61 #[inline(always)]
62 fn arm_thread_exit(slot: &$crate::LocalAllocatorSlot<$backend>) {
63 #[cfg(nightly_tls_active)]
64 {
65 $crate::arm_thread_exit(slot, &ALLOCATOR_EXIT_GUARD);
66 }
67 #[cfg(not(nightly_tls_active))]
68 {
69 let _ = slot;
71 }
72 }
73
74 #[inline(always)]
75 fn get_os_tls_key() -> &'static core::sync::atomic::AtomicU32 {
76 &OS_TLS_KEY
77 }
78
79 #[cfg(nightly_tls_active)]
80 #[inline(always)]
81 fn get_slot_nightly<R>(f: impl FnOnce(&$crate::LocalAllocatorSlot<$backend>) -> R) -> R {
82 f(&ALLOCATOR_SLOT)
83 }
84
85 #[cfg(nightly_tls_active)]
86 #[inline(always)]
87 fn get_quick_allocator_ptr() -> *mut core::ffi::c_void {
88 unsafe { QUICK_ALLOCATOR_PTR }
93 }
94
95 #[cfg(nightly_tls_active)]
96 #[inline(always)]
97 fn set_quick_allocator_ptr(ptr: *mut core::ffi::c_void) {
98 unsafe { QUICK_ALLOCATOR_PTR = ptr; }
103 }
104 }
105
106 #[cfg(all(nightly_tls_active, not(miri)))]
108 type SelectedTls = $crate::tls::NightlyTls<$backend, SlotAccess>;
109
110 #[cfg(any(
111 miri,
112 all(not(nightly_tls_active), feature = "std_tls")
113 ))]
114 type SelectedTls = $crate::tls::CachedCellTls<$backend, SlotAccess>;
115
116 #[cfg(all(not(nightly_tls_active), not(feature = "std_tls"), all(windows, target_arch = "x86_64"), not(miri)))]
117 type SelectedTls = $crate::tls::AsmTls<$backend, SlotAccess>;
118
119 #[cfg(all(not(nightly_tls_active), not(feature = "std_tls"), any(not(all(windows, target_arch = "x86_64")), miri)))]
120 type SelectedTls = $crate::tls::NativeOsTls<$backend, SlotAccess>;
121
122 #[cfg(nightly_tls_active)]
127 #[thread_local]
128 static ENCRYPTED_ALLOCATOR_SLOT: $crate::LocalAllocatorSlot<$backend> =
129 $crate::LocalAllocatorSlot::new();
130
131 #[cfg(not(nightly_tls_active))]
132 std::thread_local! {
133 static ENCRYPTED_ALLOCATOR_SLOT: $crate::LocalAllocatorSlot<$backend> = const {
134 $crate::LocalAllocatorSlot::new()
135 };
136 }
137
138 std::thread_local! {
139 static ENCRYPTED_CACHED_SLOT_PTR: core::cell::Cell<*mut core::ffi::c_void> = const {
140 core::cell::Cell::new(core::ptr::null_mut())
141 };
142
143 #[cfg(nightly_tls_active)]
144 static ENCRYPTED_ALLOCATOR_EXIT_GUARD: $crate::ThreadExitReclaim<$backend> = const {
145 $crate::ThreadExitReclaim::new()
146 };
147 }
148
149 #[cfg(nightly_tls_active)]
150 #[thread_local]
151 static mut ENCRYPTED_QUICK_ALLOCATOR_PTR: *mut core::ffi::c_void = core::ptr::null_mut();
152
153 static ENCRYPTED_OS_TLS_KEY: core::sync::atomic::AtomicU32 =
154 core::sync::atomic::AtomicU32::new(u32::MAX);
155
156 struct EncryptedSlotAccess;
157 impl $crate::tls::TlsSlotAccess<$backend> for EncryptedSlotAccess {
158 #[inline(always)]
159 fn get_slot_standard<R>(
160 f: impl FnOnce(&$crate::LocalAllocatorSlot<$backend>) -> R,
161 ) -> R {
162 #[cfg(nightly_tls_active)]
163 {
164 f(&ENCRYPTED_ALLOCATOR_SLOT)
165 }
166 #[cfg(not(nightly_tls_active))]
167 {
168 ENCRYPTED_ALLOCATOR_SLOT.with(f)
169 }
170 }
171
172 #[inline(always)]
173 fn get_cached_cell<R>(
174 f: impl FnOnce(&core::cell::Cell<*mut core::ffi::c_void>) -> R,
175 ) -> R {
176 ENCRYPTED_CACHED_SLOT_PTR.with(f)
177 }
178
179 #[inline(always)]
180 fn arm_thread_exit(slot: &$crate::LocalAllocatorSlot<$backend>) {
181 #[cfg(nightly_tls_active)]
182 {
183 $crate::arm_thread_exit(slot, &ENCRYPTED_ALLOCATOR_EXIT_GUARD);
184 }
185 #[cfg(not(nightly_tls_active))]
186 {
187 let _ = slot;
188 }
189 }
190
191 #[inline(always)]
192 fn get_os_tls_key() -> &'static core::sync::atomic::AtomicU32 {
193 &ENCRYPTED_OS_TLS_KEY
194 }
195
196 #[cfg(nightly_tls_active)]
197 #[inline(always)]
198 fn get_slot_nightly<R>(
199 f: impl FnOnce(&$crate::LocalAllocatorSlot<$backend>) -> R,
200 ) -> R {
201 f(&ENCRYPTED_ALLOCATOR_SLOT)
202 }
203
204 #[cfg(nightly_tls_active)]
205 #[inline(always)]
206 fn get_quick_allocator_ptr() -> *mut core::ffi::c_void {
207 unsafe { ENCRYPTED_QUICK_ALLOCATOR_PTR }
211 }
212
213 #[cfg(nightly_tls_active)]
214 #[inline(always)]
215 fn set_quick_allocator_ptr(ptr: *mut core::ffi::c_void) {
216 unsafe { ENCRYPTED_QUICK_ALLOCATOR_PTR = ptr; }
220 }
221 }
222
223 #[cfg(all(nightly_tls_active, not(miri)))]
224 type EncryptedSelectedTls = $crate::tls::NightlyTls<$backend, EncryptedSlotAccess>;
225
226 #[cfg(any(
227 miri,
228 all(not(nightly_tls_active), feature = "std_tls")
229 ))]
230 type EncryptedSelectedTls =
231 $crate::tls::CachedCellTls<$backend, EncryptedSlotAccess>;
232
233 #[cfg(all(not(nightly_tls_active), not(feature = "std_tls"), all(windows, target_arch = "x86_64"), not(miri)))]
234 type EncryptedSelectedTls = $crate::tls::AsmTls<$backend, EncryptedSlotAccess>;
235
236 #[cfg(all(not(nightly_tls_active), not(feature = "std_tls"), any(not(all(windows, target_arch = "x86_64")), miri)))]
237 type EncryptedSelectedTls =
238 $crate::tls::NativeOsTls<$backend, EncryptedSlotAccess>;
239
240 impl $crate::tls_slot::PolicySlotSelection<$backend>
241 for mnemosyne_core::policy::StandardPolicy
242 {
243 #[inline(always)]
244 fn with_allocator<R>(
245 f: impl FnOnce(&mut $crate::ThreadAllocator<$backend>) -> R,
246 ) -> Option<R> {
247 <SelectedTls as $crate::tls::TlsProvider<$backend>>::with_allocator(f)
248 }
249
250 #[inline(always)]
251 unsafe fn with_allocator_unguarded<R>(
252 f: impl FnOnce(&mut $crate::ThreadAllocator<$backend>) -> R,
253 ) -> Option<R> {
254 unsafe { <SelectedTls as $crate::tls::TlsProvider<$backend>>::with_allocator_unguarded(f) }
259 }
260
261 #[inline(always)]
262 fn get_allocator_ptr() -> *mut core::ffi::c_void {
263 $crate::internal::ensure_options_initialized();
264 <SelectedTls as $crate::tls::TlsProvider<$backend>>::get_allocator_ptr()
265 }
266
267 #[inline(always)]
268 fn get_allocator_ptr_raw() -> *mut core::ffi::c_void {
269 <SelectedTls as $crate::tls::TlsProvider<$backend>>::get_allocator_ptr_raw()
270 }
271 }
272
273 impl $crate::tls_slot::PolicySlotSelection<$backend>
274 for mnemosyne_core::policy::SecurePolicy
275 {
276 #[inline(always)]
277 fn with_allocator<R>(
278 f: impl FnOnce(&mut $crate::ThreadAllocator<$backend>) -> R,
279 ) -> Option<R> {
280 <SelectedTls as $crate::tls::TlsProvider<$backend>>::with_allocator(f)
281 }
282
283 #[inline(always)]
284 unsafe fn with_allocator_unguarded<R>(
285 f: impl FnOnce(&mut $crate::ThreadAllocator<$backend>) -> R,
286 ) -> Option<R> {
287 unsafe { <SelectedTls as $crate::tls::TlsProvider<$backend>>::with_allocator_unguarded(f) }
292 }
293
294 #[inline(always)]
295 fn get_allocator_ptr() -> *mut core::ffi::c_void {
296 $crate::internal::ensure_options_initialized();
297 <SelectedTls as $crate::tls::TlsProvider<$backend>>::get_allocator_ptr()
298 }
299
300 #[inline(always)]
301 fn get_allocator_ptr_raw() -> *mut core::ffi::c_void {
302 <SelectedTls as $crate::tls::TlsProvider<$backend>>::get_allocator_ptr_raw()
303 }
304 }
305
306 impl $crate::tls_slot::PolicySlotSelection<$backend>
307 for mnemosyne_core::policy::HardenedPolicy
308 {
309 #[inline(always)]
310 fn with_allocator<R>(
311 f: impl FnOnce(&mut $crate::ThreadAllocator<$backend>) -> R,
312 ) -> Option<R> {
313 <EncryptedSelectedTls as $crate::tls::TlsProvider<$backend>>::with_allocator(f)
314 }
315
316 #[inline(always)]
317 unsafe fn with_allocator_unguarded<R>(
318 f: impl FnOnce(&mut $crate::ThreadAllocator<$backend>) -> R,
319 ) -> Option<R> {
320 unsafe { <EncryptedSelectedTls as $crate::tls::TlsProvider<$backend>>::with_allocator_unguarded(f) }
325 }
326
327 #[inline(always)]
328 fn get_allocator_ptr() -> *mut core::ffi::c_void {
329 $crate::internal::ensure_options_initialized();
330 <EncryptedSelectedTls as $crate::tls::TlsProvider<$backend>>::get_allocator_ptr()
331 }
332
333 #[inline(always)]
334 fn get_allocator_ptr_raw() -> *mut core::ffi::c_void {
335 <EncryptedSelectedTls as $crate::tls::TlsProvider<$backend>>::get_allocator_ptr_raw()
336 }
337 }
338
339 impl $crate::LocalAllocatorSelector<$backend> for $backend {
340 #[inline(always)]
341 fn with_allocator<R>(
342 f: impl FnOnce(&mut $crate::ThreadAllocator<$backend>) -> R,
343 ) -> Option<R> {
344 <SelectedTls as $crate::tls::TlsProvider<$backend>>::with_allocator(f)
345 }
346
347 #[inline(always)]
348 unsafe fn with_allocator_unguarded<R>(
349 f: impl FnOnce(&mut $crate::ThreadAllocator<$backend>) -> R,
350 ) -> Option<R> {
351 unsafe { <SelectedTls as $crate::tls::TlsProvider<$backend>>::with_allocator_unguarded(f) }
355 }
356
357 #[inline(always)]
358 fn get_allocator_ptr() -> *mut core::ffi::c_void {
359 $crate::internal::ensure_options_initialized();
360 <SelectedTls as $crate::tls::TlsProvider<$backend>>::get_allocator_ptr()
361 }
362
363 #[inline(always)]
364 fn get_allocator_ptr_raw() -> *mut core::ffi::c_void {
365 <SelectedTls as $crate::tls::TlsProvider<$backend>>::get_allocator_ptr_raw()
366 }
367
368 #[inline(always)]
369 fn register_current_allocator_ptr(ptr: *mut core::ffi::c_void) {
370 <SelectedTls as $crate::tls::TlsProvider<$backend>>::register_current_allocator_ptr(ptr);
371 <EncryptedSelectedTls as $crate::tls::TlsProvider<$backend>>::register_current_allocator_ptr(ptr);
372 }
373
374 #[inline(always)]
375 fn with_allocator_for_policy<P: mnemosyne_core::AllocPolicy, R>(
376 f: impl FnOnce(&mut $crate::ThreadAllocator<$backend>) -> R,
377 ) -> Option<R> {
378 if P::ENABLE_FREE_LIST_ENCRYPTION {
379 <EncryptedSelectedTls as $crate::tls::TlsProvider<$backend>>::with_allocator(f)
380 } else {
381 <SelectedTls as $crate::tls::TlsProvider<$backend>>::with_allocator(f)
382 }
383 }
384
385 #[inline(always)]
386 unsafe fn with_allocator_unguarded_for_policy<P: mnemosyne_core::AllocPolicy, R>(
387 f: impl FnOnce(&mut $crate::ThreadAllocator<$backend>) -> R,
388 ) -> Option<R> {
389 if P::ENABLE_FREE_LIST_ENCRYPTION {
390 unsafe { <EncryptedSelectedTls as $crate::tls::TlsProvider<$backend>>::with_allocator_unguarded(f) }
395 } else {
396 unsafe { <SelectedTls as $crate::tls::TlsProvider<$backend>>::with_allocator_unguarded(f) }
398 }
399 }
400
401 #[inline(always)]
402 fn get_allocator_ptr_for_policy<P: mnemosyne_core::AllocPolicy>() -> *mut core::ffi::c_void {
403 $crate::internal::ensure_options_initialized();
404 if P::ENABLE_FREE_LIST_ENCRYPTION {
405 <EncryptedSelectedTls as $crate::tls::TlsProvider<$backend>>::get_allocator_ptr()
406 } else {
407 <SelectedTls as $crate::tls::TlsProvider<$backend>>::get_allocator_ptr()
408 }
409 }
410
411 #[inline(always)]
412 fn get_allocator_ptr_raw_for_policy<P: mnemosyne_core::AllocPolicy>() -> *mut core::ffi::c_void {
413 if P::ENABLE_FREE_LIST_ENCRYPTION {
414 <EncryptedSelectedTls as $crate::tls::TlsProvider<$backend>>::get_allocator_ptr_raw()
415 } else {
416 <SelectedTls as $crate::tls::TlsProvider<$backend>>::get_allocator_ptr_raw()
417 }
418 }
419
420 #[inline(always)]
421 fn get_allocator_ptr_raw_for_encryption<const ENCRYPTED: bool>() -> *mut core::ffi::c_void {
422 if ENCRYPTED {
423 <EncryptedSelectedTls as $crate::tls::TlsProvider<$backend>>::get_allocator_ptr_raw()
424 } else {
425 <SelectedTls as $crate::tls::TlsProvider<$backend>>::get_allocator_ptr_raw()
426 }
427 }
428 }
429 };
430 };
431}
432
433impl_local_allocator_selector!(mnemosyne_backend::MemoryBackendWrapper);
434impl_local_allocator_selector!(mnemosyne_backend::CudaUnifiedBackend);
435impl_local_allocator_selector!(mnemosyne_backend::CudaDeviceBackend);
436impl_local_allocator_selector!(mnemosyne_backend::CudaHbmBackend);
437impl_local_allocator_selector!(mnemosyne_backend::CudaGddrBackend);
438impl_local_allocator_selector!(mnemosyne_backend::CudaHostPinnedBackend);