diff --git a/crates/sel4/src/state/mod.rs b/crates/sel4/src/state/mod.rs index 849dc45d5..4b8c3e968 100644 --- a/crates/sel4/src/state/mod.rs +++ b/crates/sel4/src/state/mod.rs @@ -13,87 +13,7 @@ mod token; #[allow(unused_imports)] use token::{Accessor, BorrowError, BorrowMutError, SyncToken, TokenCell, UnsyncToken}; -/// The strategy for discovering the current thread's IPC buffer which uses thread-local state. -/// -/// This thread-local state can be modified using [`with_ipc_buffer`] and [`set_ipc_buffer`]. -/// -/// Requires the `"state"` feature to be enabled. -#[derive(Debug, Copy, Clone, Default, PartialEq, Eq, Hash)] -pub struct ImplicitInvocationContext; - -impl ImplicitInvocationContext { - pub const fn new() -> Self { - Self - } -} - -impl InvocationContext for ImplicitInvocationContext { - fn with_context(&mut self, f: impl FnOnce(&mut IpcBuffer) -> T) -> T { - with_ipc_buffer_mut(f) - } -} - -/// Sets the IPC buffer that this crate will use for this thread. -/// -/// This function does not modify kernel state. It only affects this crate's thread-local state. -/// -/// Requires the `"state"` feature to be enabled. -pub fn set_ipc_buffer(ipc_buffer: &'static mut IpcBuffer) { - try_with_ipc_buffer_slot_mut(|slot| { - *slot.unwrap() = Some(ipc_buffer); - }) -} - -/// Provides access to this thread's IPC buffer. -/// -/// Requires the `"state"` feature to be enabled. -pub fn with_ipc_buffer(f: F) -> T -where - F: FnOnce(&IpcBuffer) -> T, -{ - try_with_ipc_buffer_slot(|buf| f(buf.unwrap().as_ref().unwrap())) -} - -/// Provides mutable access to this thread's IPC buffer. -/// -/// Requires the `"state"` feature to be enabled. -pub fn with_ipc_buffer_mut(f: F) -> T -where - F: FnOnce(&mut IpcBuffer) -> T, -{ - try_with_ipc_buffer_slot_mut(|buf| f(buf.unwrap().as_mut().unwrap())) -} - -/// Provides low-level access to this thread's IPC buffer. -/// -/// This function does not modify kernel state. It only affects this crate's thread-local state. -/// -/// Requires the `"state"` feature to be enabled. -pub fn try_with_ipc_buffer_slot(f: F) -> T -where - F: FnOnce(Result<&Option<&'static mut IpcBuffer>, BorrowError>) -> T, -{ - IPC_BUFFER.0.try_with(f) -} - -/// Provides low-level mutable access to this thread's IPC buffer. -/// -/// This function does not modify kernel state. It only affects this crate's thread-local state. -/// -/// Requires the `"state"` feature to be enabled. -pub fn try_with_ipc_buffer_slot_mut(f: F) -> T -where - F: FnOnce(Result<&mut Option<&'static mut IpcBuffer>, BorrowMutError>) -> T, -{ - IPC_BUFFER.0.try_with_mut(f) -} - -/// Returns whether this crate's IPC buffer slot is thread-local. -/// -/// Requires the `"state"` feature to be enabled. -pub const fn ipc_buffer_is_thread_local() -> bool { - STATE_IS_THREAD_LOCAL -} +// // // #[repr(transparent)] struct SyncUnsafeCell(UnsafeCell); @@ -158,6 +78,13 @@ macro_rules! maybe_extern { } } +// // // + +maybe_extern! { + __sel4_ipc_buffer: SyncUnsafeCell> = + SyncUnsafeCell(UnsafeCell::new(None)); +} + struct IpcBufferAccessor; impl Accessor> for IpcBufferAccessor { @@ -176,7 +103,84 @@ maybe_add_thread_local_attr! { }; } -maybe_extern! { - __sel4_ipc_buffer: SyncUnsafeCell> = - SyncUnsafeCell(UnsafeCell::new(None)); +/// Provides low-level access to this thread's IPC buffer. +/// +/// This function does not modify kernel state. It only affects this crate's thread-local state. +/// +/// Requires the `"state"` feature to be enabled. +pub fn try_with_ipc_buffer_slot(f: F) -> T +where + F: FnOnce(Result<&Option<&'static mut IpcBuffer>, BorrowError>) -> T, +{ + IPC_BUFFER.0.try_with(f) +} + +/// Provides low-level mutable access to this thread's IPC buffer. +/// +/// This function does not modify kernel state. It only affects this crate's thread-local state. +/// +/// Requires the `"state"` feature to be enabled. +pub fn try_with_ipc_buffer_slot_mut(f: F) -> T +where + F: FnOnce(Result<&mut Option<&'static mut IpcBuffer>, BorrowMutError>) -> T, +{ + IPC_BUFFER.0.try_with_mut(f) +} + +/// Provides access to this thread's IPC buffer. +/// +/// Requires the `"state"` feature to be enabled. +pub fn with_ipc_buffer(f: F) -> T +where + F: FnOnce(&IpcBuffer) -> T, +{ + try_with_ipc_buffer_slot(|buf| f(buf.unwrap().as_ref().unwrap())) +} + +/// Provides mutable access to this thread's IPC buffer. +/// +/// Requires the `"state"` feature to be enabled. +pub fn with_ipc_buffer_mut(f: F) -> T +where + F: FnOnce(&mut IpcBuffer) -> T, +{ + try_with_ipc_buffer_slot_mut(|buf| f(buf.unwrap().as_mut().unwrap())) +} + +/// Sets the IPC buffer that this crate will use for this thread. +/// +/// This function does not modify kernel state. It only affects this crate's thread-local state. +/// +/// Requires the `"state"` feature to be enabled. +pub fn set_ipc_buffer(ipc_buffer: &'static mut IpcBuffer) { + try_with_ipc_buffer_slot_mut(|slot| { + *slot.unwrap() = Some(ipc_buffer); + }) +} + +/// Returns whether this crate's IPC buffer slot is thread-local. +/// +/// Requires the `"state"` feature to be enabled. +pub const fn ipc_buffer_is_thread_local() -> bool { + STATE_IS_THREAD_LOCAL +} + +/// The strategy for discovering the current thread's IPC buffer which uses thread-local state. +/// +/// This thread-local state can be modified using [`with_ipc_buffer`] and [`set_ipc_buffer`]. +/// +/// Requires the `"state"` feature to be enabled. +#[derive(Debug, Copy, Clone, Default, PartialEq, Eq, Hash)] +pub struct ImplicitInvocationContext; + +impl ImplicitInvocationContext { + pub const fn new() -> Self { + Self + } +} + +impl InvocationContext for ImplicitInvocationContext { + fn with_context(&mut self, f: impl FnOnce(&mut IpcBuffer) -> T) -> T { + with_ipc_buffer_mut(f) + } }