loro_internal/
sync.rs

1#[cfg(loom)]
2pub use loom::thread;
3#[cfg(not(loom))]
4pub use std::thread;
5
6#[cfg(loom)]
7pub use loom::sync::{Mutex, MutexGuard, RwLock};
8#[cfg(not(loom))]
9pub use std::sync::{Mutex, MutexGuard, RwLock};
10
11#[cfg(loom)]
12pub use loom::sync::atomic::{AtomicBool, AtomicI64, AtomicU64, AtomicU8, AtomicUsize};
13#[cfg(not(loom))]
14pub use std::sync::atomic::{AtomicBool, AtomicI64, AtomicU64, AtomicU8, AtomicUsize};
15
16#[cfg(loom)]
17pub(crate) use my_thread_local::ThreadLocal;
18#[cfg(not(loom))]
19pub(crate) use thread_local::ThreadLocal;
20
21#[cfg(loom)]
22mod my_thread_local {
23    use std::sync::Arc;
24
25    use super::thread;
26    use super::Mutex;
27    use fxhash::FxHashMap;
28
29    #[derive(Debug)]
30    pub(crate) struct ThreadLocal<T> {
31        content: Arc<Mutex<FxHashMap<thread::ThreadId, Arc<T>>>>,
32    }
33
34    impl<T: Default> ThreadLocal<T> {
35        pub fn new() -> Self {
36            Self {
37                content: Arc::new(Mutex::new(FxHashMap::default())),
38            }
39        }
40
41        pub fn get_or_default(&self) -> Arc<T> {
42            let mut content = self.content.lock().unwrap();
43            let v = content
44                .entry(thread::current().id())
45                .or_insert_with(|| Arc::new(T::default()));
46            v.clone()
47        }
48    }
49
50    impl<T> Clone for ThreadLocal<T> {
51        fn clone(&self) -> Self {
52            Self {
53                content: self.content.clone(),
54            }
55        }
56    }
57}