sel4_panicking/count/
with_tls.rs
1use core::cell::Cell;
8use core::fmt;
9
10#[thread_local]
11static PANIC_COUNT: Cell<usize> = Cell::new(0);
12
13const MAX_PANIC_DEPTH: usize = if cfg!(feature = "alloc") { 3 } else { 1 };
14
15pub(crate) enum MustAbort {
16 MaxDepthExceeded,
17}
18
19impl fmt::Display for MustAbort {
20 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
21 match self {
22 Self::MaxDepthExceeded => {
23 write!(f, "maximum panic depth of {MAX_PANIC_DEPTH} exceeded")
24 }
25 }
26 }
27}
28
29pub(crate) fn count_panic() -> Option<MustAbort> {
30 if PANIC_COUNT.get() == MAX_PANIC_DEPTH {
31 return Some(MustAbort::MaxDepthExceeded);
32 }
33 update(&PANIC_COUNT, |count| count + 1);
34 None
35}
36
37pub(crate) fn count_panic_caught() {
38 update(&PANIC_COUNT, |count| count - 1);
39}
40
41fn update<T: Copy>(cell: &Cell<T>, f: impl FnOnce(T) -> T) -> T {
42 let old = cell.get();
43 let new = f(old);
44 cell.set(new);
45 new
46}