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}