• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2024 The percore Authors.
2 // This project is dual-licensed under Apache 2.0 and MIT terms.
3 // See LICENSE-APACHE and LICENSE-MIT for details.
4 
5 #[cfg(target_arch = "aarch64")]
6 mod aarch64;
7 #[cfg(target_arch = "aarch64")]
8 use aarch64::{mask, restore};
9 
10 use core::marker::PhantomData;
11 
12 /// Runs the given function with exceptions masked.
13 ///
14 /// Only IRQs, FIQs and SErrors can be masked. Synchronous exceptions cannot be masked and so may
15 /// still occur.
16 #[cfg(target_arch = "aarch64")]
exception_free<T>(f: impl FnOnce(ExceptionFree<'_>) -> T) -> T17 pub fn exception_free<T>(f: impl FnOnce(ExceptionFree<'_>) -> T) -> T {
18     // Mask all exceptions and save previous mask state.
19     let prev = mask();
20     // SAFETY: We just masked exceptions.
21     let token = unsafe { ExceptionFree::new() };
22 
23     let result = f(token);
24 
25     // SAFETY: `token` has been dropped by now, as its lifetime prevents `f` from storing it.
26     unsafe {
27         // Restore previous exception mask state.
28         restore(prev);
29     }
30 
31     result
32 }
33 
34 /// A token proving that exceptions are currently masked.
35 ///
36 /// Note that synchronous exceptions cannot be masked and so may still occur.
37 #[derive(Clone, Copy, Debug)]
38 pub struct ExceptionFree<'cs> {
39     _private: PhantomData<&'cs ()>,
40 }
41 
42 impl<'cs> ExceptionFree<'cs> {
43     /// Constructs a new instance of `ExceptionFree`, promising that exceptions will remain masked
44     /// for at least its lifetime.
45     ///
46     /// This usually should not be called directly; instead use [`exception_free`].
47     ///
48     /// # Safety
49     ///
50     /// `ExceptionFree` must only be constructed while exceptions are masked, and they must not be
51     /// unmasked until after it is dropped.
new() -> Self52     pub unsafe fn new() -> Self {
53         Self {
54             _private: PhantomData,
55         }
56     }
57 }
58