| pub(crate) use self::inner::*; |
| |
| #[cfg(all(loom, any(test, feature = "loom")))] |
| mod inner { |
| pub(crate) mod atomic { |
| pub use loom::sync::atomic::*; |
| pub use std::sync::atomic::Ordering; |
| } |
| pub(crate) use loom::{ |
| cell::UnsafeCell, hint, lazy_static, sync::Mutex, thread::yield_now, thread_local, |
| }; |
| |
| pub(crate) mod alloc { |
| #![allow(dead_code)] |
| use loom::alloc; |
| use std::fmt; |
| /// Track allocations, detecting leaks |
| /// |
| /// This is a version of `loom::alloc::Track` that adds a missing |
| /// `Default` impl. |
| pub struct Track<T>(alloc::Track<T>); |
| |
| impl<T> Track<T> { |
| /// Track a value for leaks |
| #[inline(always)] |
| pub fn new(value: T) -> Track<T> { |
| Track(alloc::Track::new(value)) |
| } |
| |
| /// Get a reference to the value |
| #[inline(always)] |
| pub fn get_ref(&self) -> &T { |
| self.0.get_ref() |
| } |
| |
| /// Get a mutable reference to the value |
| #[inline(always)] |
| pub fn get_mut(&mut self) -> &mut T { |
| self.0.get_mut() |
| } |
| |
| /// Stop tracking the value for leaks |
| #[inline(always)] |
| pub fn into_inner(self) -> T { |
| self.0.into_inner() |
| } |
| } |
| |
| impl<T: fmt::Debug> fmt::Debug for Track<T> { |
| fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| self.0.fmt(f) |
| } |
| } |
| |
| impl<T: Default> Default for Track<T> { |
| fn default() -> Self { |
| Self::new(T::default()) |
| } |
| } |
| } |
| } |
| |
| #[cfg(not(all(loom, any(feature = "loom", test))))] |
| mod inner { |
| #![allow(dead_code)] |
| pub(crate) use lazy_static::lazy_static; |
| pub(crate) use std::{ |
| sync::{atomic, Mutex}, |
| thread::yield_now, |
| thread_local, |
| }; |
| |
| pub(crate) mod hint { |
| #[inline(always)] |
| pub(crate) fn spin_loop() { |
| // MSRV: std::hint::spin_loop() stabilized in 1.49.0 |
| #[allow(deprecated)] |
| super::atomic::spin_loop_hint() |
| } |
| } |
| |
| #[derive(Debug)] |
| pub(crate) struct UnsafeCell<T>(std::cell::UnsafeCell<T>); |
| |
| impl<T> UnsafeCell<T> { |
| pub fn new(data: T) -> UnsafeCell<T> { |
| UnsafeCell(std::cell::UnsafeCell::new(data)) |
| } |
| |
| #[inline(always)] |
| pub fn with<F, R>(&self, f: F) -> R |
| where |
| F: FnOnce(*const T) -> R, |
| { |
| f(self.0.get()) |
| } |
| |
| #[inline(always)] |
| pub fn with_mut<F, R>(&self, f: F) -> R |
| where |
| F: FnOnce(*mut T) -> R, |
| { |
| f(self.0.get()) |
| } |
| } |
| |
| pub(crate) mod alloc { |
| /// Track allocations, detecting leaks |
| #[derive(Debug, Default)] |
| pub struct Track<T> { |
| value: T, |
| } |
| |
| impl<T> Track<T> { |
| /// Track a value for leaks |
| #[inline(always)] |
| pub fn new(value: T) -> Track<T> { |
| Track { value } |
| } |
| |
| /// Get a reference to the value |
| #[inline(always)] |
| pub fn get_ref(&self) -> &T { |
| &self.value |
| } |
| |
| /// Get a mutable reference to the value |
| #[inline(always)] |
| pub fn get_mut(&mut self) -> &mut T { |
| &mut self.value |
| } |
| |
| /// Stop tracking the value for leaks |
| #[inline(always)] |
| pub fn into_inner(self) -> T { |
| self.value |
| } |
| } |
| } |
| } |