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