#[cfg(target_arch = "aarch64")]
mod aarch64;
#[cfg(target_arch = "aarch64")]
use aarch64::ExceptionMask;
#[cfg(target_arch = "arm")]
mod aarch32;
#[cfg(target_arch = "arm")]
use aarch32::ExceptionMask;
use core::marker::PhantomData;
#[cfg(any(target_arch = "aarch64", target_arch = "arm"))]
struct ExceptionGuard {
prev: ExceptionMask,
}
#[cfg(any(target_arch = "aarch64", target_arch = "arm"))]
impl ExceptionGuard {
unsafe fn mask<'cs>() -> (Self, ExceptionFree<'cs>) {
let guard = Self {
prev: ExceptionMask::mask(),
};
let token = unsafe { ExceptionFree::new() };
(guard, token)
}
}
#[cfg(any(target_arch = "aarch64", target_arch = "arm"))]
impl Drop for ExceptionGuard {
fn drop(&mut self) {
unsafe {
self.prev.restore();
}
}
}
#[cfg(any(target_arch = "aarch64", target_arch = "arm"))]
pub fn exception_free<T>(f: impl FnOnce(ExceptionFree<'_>) -> T) -> T {
let (scope_guard, token) = unsafe { ExceptionGuard::mask() };
let result = f(token);
drop(scope_guard);
result
}
#[derive(Clone, Copy, Debug)]
pub struct ExceptionFree<'cs> {
_private: PhantomData<&'cs ()>,
}
impl<'cs> ExceptionFree<'cs> {
pub unsafe fn new() -> Self {
Self {
_private: PhantomData,
}
}
}