1pub(crate) use self::inner::*;
2
3#[cfg(all(loom, any(test, feature = "loom")))]
4mod inner {
5 pub(crate) mod atomic {
6 pub use loom::sync::atomic::*;
7 pub use std::sync::atomic::Ordering;
8 }
9 pub(crate) use loom::{
10 cell::UnsafeCell, hint, lazy_static, sync::Mutex, thread::yield_now, thread_local,
11 };
12
13 pub(crate) mod alloc {
14 #![allow(dead_code)]
15 use loom::alloc;
16 use std::fmt;
17 /// Track allocations, detecting leaks
18 ///
19 /// This is a version of `loom::alloc::Track` that adds a missing
20 /// `Default` impl.
21 pub struct Track<T>(alloc::Track<T>);
22
23 impl<T> Track<T> {
24 /// Track a value for leaks
25 #[inline(always)]
26 pub fn new(value: T) -> Track<T> {
27 Track(alloc::Track::new(value))
28 }
29
30 /// Get a reference to the value
31 #[inline(always)]
32 pub fn get_ref(&self) -> &T {
33 self.0.get_ref()
34 }
35
36 /// Get a mutable reference to the value
37 #[inline(always)]
38 pub fn get_mut(&mut self) -> &mut T {
39 self.0.get_mut()
40 }
41
42 /// Stop tracking the value for leaks
43 #[inline(always)]
44 pub fn into_inner(self) -> T {
45 self.0.into_inner()
46 }
47 }
48
49 impl<T: fmt::Debug> fmt::Debug for Track<T> {
50 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
51 self.0.fmt(f)
52 }
53 }
54
55 impl<T: Default> Default for Track<T> {
56 fn default() -> Self {
57 Self::new(T::default())
58 }
59 }
60 }
61}
62
63#[cfg(not(all(loom, any(feature = "loom", test))))]
64mod inner {
65 #![allow(dead_code)]
66 pub(crate) use lazy_static::lazy_static;
67 pub(crate) use std::{
68 sync::{atomic, Mutex},
69 thread::yield_now,
70 thread_local,
71 };
72
73 pub(crate) mod hint {
74 #[inline(always)]
75 pub(crate) fn spin_loop() {
76 // MSRV: std::hint::spin_loop() stabilized in 1.49.0
77 #[allow(deprecated)]
78 super::atomic::spin_loop_hint()
79 }
80 }
81
82 #[derive(Debug)]
83 pub(crate) struct UnsafeCell<T>(std::cell::UnsafeCell<T>);
84
85 impl<T> UnsafeCell<T> {
86 pub fn new(data: T) -> UnsafeCell<T> {
87 UnsafeCell(std::cell::UnsafeCell::new(data))
88 }
89
90 #[inline(always)]
91 pub fn with<F, R>(&self, f: F) -> R
92 where
93 F: FnOnce(*const T) -> R,
94 {
95 f(self.0.get())
96 }
97
98 #[inline(always)]
99 pub fn with_mut<F, R>(&self, f: F) -> R
100 where
101 F: FnOnce(*mut T) -> R,
102 {
103 f(self.0.get())
104 }
105 }
106
107 pub(crate) mod alloc {
108 /// Track allocations, detecting leaks
109 #[derive(Debug, Default)]
110 pub struct Track<T> {
111 value: T,
112 }
113
114 impl<T> Track<T> {
115 /// Track a value for leaks
116 #[inline(always)]
117 pub fn new(value: T) -> Track<T> {
118 Track { value }
119 }
120
121 /// Get a reference to the value
122 #[inline(always)]
123 pub fn get_ref(&self) -> &T {
124 &self.value
125 }
126
127 /// Get a mutable reference to the value
128 #[inline(always)]
129 pub fn get_mut(&mut self) -> &mut T {
130 &mut self.value
131 }
132
133 /// Stop tracking the value for leaks
134 #[inline(always)]
135 pub fn into_inner(self) -> T {
136 self.value
137 }
138 }
139 }
140}
141