1 pub(crate) use self::inner::*;
2 
3 #[cfg(all(loom, any(test, feature = "loom")))]
4 mod 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)]
new(value: T) -> Track<T>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)]
get_ref(&self) -> &T32             pub fn get_ref(&self) -> &T {
33                 self.0.get_ref()
34             }
35 
36             /// Get a mutable reference to the value
37             #[inline(always)]
get_mut(&mut self) -> &mut T38             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)]
into_inner(self) -> T44             pub fn into_inner(self) -> T {
45                 self.0.into_inner()
46             }
47         }
48 
49         impl<T: fmt::Debug> fmt::Debug for Track<T> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result50             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> {
default() -> Self56             fn default() -> Self {
57                 Self::new(T::default())
58             }
59         }
60     }
61 }
62 
63 #[cfg(not(all(loom, any(feature = "loom", test))))]
64 mod 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)]
spin_loop()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> {
new(data: T) -> UnsafeCell<T>86         pub fn new(data: T) -> UnsafeCell<T> {
87             UnsafeCell(std::cell::UnsafeCell::new(data))
88         }
89 
90         #[inline(always)]
with<F, R>(&self, f: F) -> R where F: FnOnce(*const T) -> R,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)]
with_mut<F, R>(&self, f: F) -> R where F: FnOnce(*mut T) -> R,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)]
new(value: T) -> Track<T>117             pub fn new(value: T) -> Track<T> {
118                 Track { value }
119             }
120 
121             /// Get a reference to the value
122             #[inline(always)]
get_ref(&self) -> &T123             pub fn get_ref(&self) -> &T {
124                 &self.value
125             }
126 
127             /// Get a mutable reference to the value
128             #[inline(always)]
get_mut(&mut self) -> &mut T129             pub fn get_mut(&mut self) -> &mut T {
130                 &mut self.value
131             }
132 
133             /// Stop tracking the value for leaks
134             #[inline(always)]
into_inner(self) -> T135             pub fn into_inner(self) -> T {
136                 self.value
137             }
138         }
139     }
140 }
141