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)] |
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))))] |
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)] |
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 | |