1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
use std::mem;
use std::sync::atomic::{AtomicU64, Ordering};
use std::thread;
static MAIN_THREAD_ID: AtomicU64 = AtomicU64::new(0);
#[inline]
fn current_thread_id() -> u64 {
unsafe { mem::transmute(thread::current().id()) }
}
pub fn assert_main_thread() {
let thread_id = current_thread_id();
let main_thread_id = MAIN_THREAD_ID.load(Ordering::Acquire);
if thread_id != main_thread_id {
panic!(
"Main thread assertion failed {} != {}",
thread_id, main_thread_id
);
}
}
pub fn claim_main_thread() {
let thread_id = current_thread_id();
let old_thread_id =
MAIN_THREAD_ID.compare_exchange(0, thread_id, Ordering::AcqRel, Ordering::Acquire);
match old_thread_id {
Ok(0) => (),
Ok(_) => unreachable!(),
Err(0) => {
tracing::warn!("The main thread status was already claimed by the current thread.")
}
Err(k) => panic!(
"The main thread status has already been claimed by thread {}",
k
),
}
}
pub fn release_main_thread() {
let thread_id = current_thread_id();
let old_thread_id =
MAIN_THREAD_ID.compare_exchange(thread_id, 0, Ordering::AcqRel, Ordering::Acquire);
match old_thread_id {
Ok(n) if n == thread_id => (),
Ok(_) => unreachable!(),
Err(0) => tracing::warn!("The main thread status was already vacant."),
Err(k) => panic!(
"The main thread status has already been claimed by thread {}",
k
),
}
}
#[allow(unused_macros)]
macro_rules! borrow {
($val:expr) => {{
use anyhow::Context;
$val.try_borrow().with_context(|| {
format!(
"[{}:{}] {}",
std::file!(),
std::line!(),
std::stringify!($val)
)
})
}};
}
#[allow(unused_macros)]
macro_rules! borrow_mut {
($val:expr) => {{
use anyhow::Context;
$val.try_borrow_mut().with_context(|| {
format!(
"[{}:{}] {}",
std::file!(),
std::line!(),
std::stringify!($val)
)
})
}};
}