mycelium_util/
loom.rs

1#[allow(unused_imports)]
2pub(crate) use self::inner::*;
3
4#[cfg(loom)]
5mod inner {
6    pub use loom::{alloc, hint, model, sync, thread};
7}
8
9#[cfg(not(loom))]
10mod inner {
11    #![allow(dead_code)]
12
13    #[cfg(test)]
14    pub(crate) mod thread {
15        #[allow(unused_imports)]
16        pub(crate) use std::thread::{JoinHandle, Thread};
17        pub fn spawn<F, T>(f: F) -> JoinHandle<T>
18        where
19            F: FnOnce() -> T,
20            F: Send + 'static,
21            T: Send + 'static,
22        {
23            let dispatch = tracing::dispatch::Dispatch::default();
24            std::thread::spawn(move || {
25                let _guard = tracing::dispatch::set_default(&dispatch);
26                test_info!("thread spawned");
27                f()
28            })
29        }
30    }
31
32    #[cfg(test)]
33    pub(crate) fn model(f: impl Fn()) {
34        let _trace = crate::test_util::trace_init();
35        f()
36    }
37
38    #[cfg(test)]
39    pub(crate) mod model {
40        #[non_exhaustive]
41        #[derive(Default)]
42        pub(crate) struct Builder {
43            pub(crate) max_threads: usize,
44            pub(crate) max_branches: usize,
45            pub(crate) max_permutations: Option<usize>,
46            // pub(crate) max_duration: Option<Duration>,
47            pub(crate) preemption_bound: Option<usize>,
48            // pub(crate) checkpoint_file: Option<PathBuf>,
49            pub(crate) checkpoint_interval: usize,
50            pub(crate) location: bool,
51            pub(crate) log: bool,
52        }
53
54        impl Builder {
55            pub(crate) fn new() -> Self {
56                Self::default()
57            }
58
59            pub(crate) fn check(&self, f: impl Fn()) {
60                super::model(f)
61            }
62        }
63    }
64
65    pub(crate) mod alloc {
66        /// Track allocations, detecting leaks
67        #[derive(Debug, Default)]
68        pub struct Track<T> {
69            value: T,
70        }
71
72        impl<T> Track<T> {
73            /// Track a value for leaks
74            #[inline(always)]
75            pub fn new(value: T) -> Track<T> {
76                Track { value }
77            }
78
79            /// Get a reference to the value
80            #[inline(always)]
81            pub fn get_ref(&self) -> &T {
82                &self.value
83            }
84
85            /// Get a mutable reference to the value
86            #[inline(always)]
87            pub fn get_mut(&mut self) -> &mut T {
88                &mut self.value
89            }
90
91            /// Stop tracking the value for leaks
92            #[inline(always)]
93            pub fn into_inner(self) -> T {
94                self.value
95            }
96        }
97    }
98}