Skip to content

Commit

Permalink
create/sel4-panicking: Refactor
Browse files Browse the repository at this point in the history
Signed-off-by: Nick Spinale <[email protected]>
  • Loading branch information
nspin committed Jan 18, 2024
1 parent b9588b5 commit 42569be
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 35 deletions.
4 changes: 2 additions & 2 deletions crates/private/tests/root-task/panicking/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ cfg_if::cfg_if! {
assert_eq!(r.err().unwrap().inner().downcast_ref::<String>().unwrap().as_str(), "foo");
}
} else {
use panicking::FitsWithinSmallPayload;
use panicking::SmallPayload;

fn whether_alloc() {
let r = panicking::catch_unwind(|| {
Expand All @@ -70,6 +70,6 @@ cfg_if::cfg_if! {
#[derive(Copy, Clone)]
struct Foo(usize);

impl FitsWithinSmallPayload for Foo {}
impl SmallPayload for Foo {}
}
}
3 changes: 1 addition & 2 deletions crates/sel4-microkit/src/panicking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ use sel4_panicking::set_hook as set_outer_hook;
use sel4_panicking_env::debug_println;

pub use sel4_panicking::{
catch_unwind, panic_any, ExternalPanicInfo, FitsWithinSmallPayload, PanicHook, Payload,
SmallPayloadValue, UpcastIntoPayload,
catch_unwind, panic_any, ExternalPanicInfo, PanicHook, Payload, SmallPayload, UpcastIntoPayload,
};

use crate::pd_name;
Expand Down
6 changes: 1 addition & 5 deletions crates/sel4-panicking/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,7 @@ use payload::NoPayload;
use strategy::{panic_cleanup, start_panic};

pub use hook::{set_hook, PanicHook};
pub use payload::{FitsWithinSmallPayload, Payload, SmallPayloadValue, UpcastIntoPayload};

// // //
pub use payload::{Payload, SmallPayload, UpcastIntoPayload, SMALL_PAYLOAD_MAX_SIZE};

pub struct ExternalPanicInfo<'a> {
payload: Payload,
Expand Down Expand Up @@ -110,8 +108,6 @@ fn do_panic(info: ExternalPanicInfo) -> ! {
}
}

// // //

pub fn catch_unwind<R, F: FnOnce() -> R>(f: F) -> Result<R, Payload> {
union Data<F, R> {
f: ManuallyDrop<F>,
Expand Down
35 changes: 13 additions & 22 deletions crates/sel4-panicking/src/payload/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
//

use core::mem;
use core::slice;

cfg_if::cfg_if! {
if #[cfg(feature = "alloc")] {
Expand All @@ -23,34 +22,26 @@ pub trait UpcastIntoPayload {
fn upcast_into_payload(self) -> Payload;
}

#[derive(Clone, Copy)]
pub struct SmallPayloadValue([u8; Self::SIZE]);

impl SmallPayloadValue {
pub const SIZE: usize = 32;
pub const SMALL_PAYLOAD_MAX_SIZE: usize = 32;

pub const fn ensure_fits<T: FitsWithinSmallPayload>() {
assert!(mem::size_of::<T>() <= Self::SIZE);
}
#[allow(dead_code)]
#[inline(always)]
const fn check_small_payload_size<T: SmallPayload>() {
struct Check<T>(T);

pub fn write<T: FitsWithinSmallPayload + Copy>(val: &T) -> Self {
Self::ensure_fits::<T>();
let val_bytes =
unsafe { slice::from_raw_parts(val as *const T as *const u8, mem::size_of::<T>()) };
let mut payload_arr = [0; Self::SIZE];
payload_arr[..val_bytes.len()].copy_from_slice(val_bytes);
Self(payload_arr)
impl<T> Check<T> {
const CHECK: () = assert!(
mem::size_of::<T>() <= SMALL_PAYLOAD_MAX_SIZE,
"type is is too large to implement SmallPayload",
);
}

pub fn read<T: FitsWithinSmallPayload + Copy>(&self) -> T {
Self::ensure_fits::<T>();
unsafe { mem::transmute_copy(&self.0) }
}
Check::<T>::CHECK
}

pub trait FitsWithinSmallPayload {}
pub trait SmallPayload {}

#[derive(Clone, Copy)]
pub(crate) struct NoPayload;

impl FitsWithinSmallPayload for NoPayload {}
impl SmallPayload for NoPayload {}
2 changes: 1 addition & 1 deletion crates/sel4-panicking/src/payload/with_alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use super::UpcastIntoPayload;
pub struct Payload(Box<dyn Any + Send + 'static>);

impl Payload {
pub fn new(inner: Box<dyn Any + Send + 'static>) -> Self {
fn new(inner: Box<dyn Any + Send + 'static>) -> Self {
Self(inner)
}

Expand Down
28 changes: 25 additions & 3 deletions crates/sel4-panicking/src/payload/without_alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@
//

use core::any::{Any, TypeId};
use core::mem;
use core::ptr;
use core::slice;

use super::{FitsWithinSmallPayload, SmallPayloadValue, UpcastIntoPayload};
use super::{check_small_payload_size, SmallPayload, UpcastIntoPayload, SMALL_PAYLOAD_MAX_SIZE};

pub struct Payload {
type_id: TypeId,
Expand All @@ -18,7 +21,7 @@ impl Payload {
self.type_id
}

pub fn downcast<T: FitsWithinSmallPayload + Copy + 'static>(self) -> Result<T, Self> {
pub fn downcast<T: SmallPayload + Copy + 'static>(self) -> Result<T, Self> {
if self.type_id() == TypeId::of::<T>() {
Ok(self.value.read())
} else {
Expand All @@ -27,7 +30,7 @@ impl Payload {
}
}

impl<T: FitsWithinSmallPayload + Copy + Any> UpcastIntoPayload for T {
impl<T: SmallPayload + Copy + Any> UpcastIntoPayload for T {
fn upcast_into_payload(self) -> Payload {
let type_id = self.type_id();
Payload {
Expand All @@ -36,3 +39,22 @@ impl<T: FitsWithinSmallPayload + Copy + Any> UpcastIntoPayload for T {
}
}
}

#[derive(Clone, Copy)]
struct SmallPayloadValue([u8; SMALL_PAYLOAD_MAX_SIZE]);

impl SmallPayloadValue {
fn write<T: SmallPayload + Copy>(val: &T) -> Self {
check_small_payload_size::<T>();
let val_bytes =
unsafe { slice::from_raw_parts(ptr::addr_of!(*val).cast::<u8>(), mem::size_of::<T>()) };
let mut payload_arr = [0; SMALL_PAYLOAD_MAX_SIZE];
payload_arr[..val_bytes.len()].copy_from_slice(val_bytes);
Self(payload_arr)
}

fn read<T: SmallPayload + Copy>(&self) -> T {
check_small_payload_size::<T>();
unsafe { mem::transmute_copy(&self.0) }
}
}

0 comments on commit 42569be

Please sign in to comment.