diff --git a/Cargo.lock b/Cargo.lock index e8134d2f3..55a4a1c89 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1866,6 +1866,10 @@ dependencies = [ "sel4-sys", ] +[[package]] +name = "sel4-abstract-rc" +version = "0.1.0" + [[package]] name = "sel4-async-block-io" version = "0.1.0" @@ -2635,11 +2639,14 @@ dependencies = [ name = "sel4-shared-ring-buffer-smoltcp" version = "0.1.0" dependencies = [ + "lock_api", "log", + "sel4-abstract-rc", "sel4-bounce-buffer-allocator", "sel4-externally-shared", "sel4-shared-ring-buffer", "sel4-shared-ring-buffer-bookkeeping", + "sel4-sync-trivial", "smoltcp", ] @@ -2735,6 +2742,14 @@ dependencies = [ "lock_api", "sel4", "sel4-immediate-sync-once-cell", + "sel4-sync-trivial", +] + +[[package]] +name = "sel4-sync-trivial" +version = "0.1.0" +dependencies = [ + "lock_api", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 729ca3173..98f10643f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -66,6 +66,7 @@ members = [ "crates/private/tests/root-task/verus/core", "crates/private/tests/root-task/verus/task", "crates/sel4", + "crates/sel4-abstract-rc", "crates/sel4-async/block-io", "crates/sel4-async/block-io/fat", "crates/sel4-async/io", @@ -136,6 +137,7 @@ members = [ "crates/sel4-shared-ring-buffer/smoltcp", "crates/sel4-stack", "crates/sel4-sync", + "crates/sel4-sync/trivial", "crates/sel4-synthetic-elf", "crates/sel4-test-harness", "crates/sel4/bitfield-ops", diff --git a/crates/drivers/virtio/hal-impl/src/lib.rs b/crates/drivers/virtio/hal-impl/src/lib.rs index 521312c0b..151ba122e 100644 --- a/crates/drivers/virtio/hal-impl/src/lib.rs +++ b/crates/drivers/virtio/hal-impl/src/lib.rs @@ -14,9 +14,9 @@ use virtio_drivers::{BufferDirection, Hal, PhysAddr, PAGE_SIZE}; use sel4_bounce_buffer_allocator::{Basic, BounceBufferAllocator}; use sel4_externally_shared::{ExternallySharedRef, ExternallySharedRefExt}; use sel4_immediate_sync_once_cell::ImmediateSyncOnceCell; -use sel4_sync::{lock_api::Mutex, GenericRawMutex, PanickingMutexSyncOps}; +use sel4_sync::{lock_api::Mutex, PanickingRawMutex}; -static GLOBAL_STATE: ImmediateSyncOnceCell, State>> = +static GLOBAL_STATE: ImmediateSyncOnceCell> = ImmediateSyncOnceCell::new(); struct State { @@ -56,14 +56,11 @@ impl HalImpl { BounceBufferAllocator::new(Basic::new(dma_region_size), max_alignment); GLOBAL_STATE - .set(Mutex::from_raw( - GenericRawMutex::new(PanickingMutexSyncOps::new()), - State { - dma_region, - dma_region_paddr, - bounce_buffer_allocator, - }, - )) + .set(Mutex::new(State { + dma_region, + dma_region_paddr, + bounce_buffer_allocator, + })) .ok() .unwrap(); } diff --git a/crates/examples/microkit/http-server/pds/server/src/main.rs b/crates/examples/microkit/http-server/pds/server/src/main.rs index f9418f30e..5957f0483 100644 --- a/crates/examples/microkit/http-server/pds/server/src/main.rs +++ b/crates/examples/microkit/http-server/pds/server/src/main.rs @@ -110,6 +110,7 @@ fn init() -> impl Handler { BounceBufferAllocator::new(Basic::new(dma_region.as_ptr().len()), 1); DeviceImpl::new( + Default::default(), dma_region, bounce_buffer_allocator, RingBuffers::from_ptrs_using_default_initialization_strategy_for_role( diff --git a/crates/examples/root-task/spawn-task/child/src/runtime.rs b/crates/examples/root-task/spawn-task/child/src/runtime.rs index e3a6ada98..4779aacc4 100644 --- a/crates/examples/root-task/spawn-task/child/src/runtime.rs +++ b/crates/examples/root-task/spawn-task/child/src/runtime.rs @@ -10,7 +10,7 @@ use sel4::CapTypeForFrameObjectOfFixedSize; use sel4_dlmalloc::{StaticDlmallocGlobalAlloc, StaticHeap}; use sel4_panicking::catch_unwind; use sel4_panicking_env::abort; -use sel4_sync::{GenericRawMutex, PanickingMutexSyncOps}; +use sel4_sync::PanickingRawMutex; use crate::main; @@ -24,12 +24,9 @@ static STATIC_HEAP: StaticHeap = StaticHeap::new(); #[global_allocator] static GLOBAL_ALLOCATOR: StaticDlmallocGlobalAlloc< - GenericRawMutex, + PanickingRawMutex, &'static StaticHeap, -> = StaticDlmallocGlobalAlloc::new( - GenericRawMutex::new(PanickingMutexSyncOps::new()), - &STATIC_HEAP, -); +> = StaticDlmallocGlobalAlloc::new(PanickingRawMutex::new(), &STATIC_HEAP); sel4_panicking_env::register_debug_put_char!(sel4::debug_put_char); diff --git a/crates/private/support/sel4-simple-task/runtime/src/global_allocator.rs b/crates/private/support/sel4-simple-task/runtime/src/global_allocator.rs index a6159f7f1..e634e8aa2 100644 --- a/crates/private/support/sel4-simple-task/runtime/src/global_allocator.rs +++ b/crates/private/support/sel4-simple-task/runtime/src/global_allocator.rs @@ -5,23 +5,28 @@ // use sel4_dlmalloc::{StaticDlmallocGlobalAlloc, StaticHeapBounds}; -use sel4_sync::{AbstractMutexSyncOps, GenericRawMutex}; +use sel4_sync::{GenericRawMutex, MutexSyncOps}; use crate::{get_static_heap_bounds, get_static_heap_mutex_notification}; #[global_allocator] #[allow(clippy::type_complexity)] static GLOBAL_ALLOCATOR: StaticDlmallocGlobalAlloc< - GenericRawMutex>, + GenericRawMutex, fn() -> StaticHeapBounds, > = StaticDlmallocGlobalAlloc::new( - GenericRawMutex::new(AbstractMutexSyncOps { - signal: || { - get_static_heap_mutex_notification().signal(); - }, - wait: || { - get_static_heap_mutex_notification().wait(); - }, - }), + GenericRawMutex::new(MutexSyncOpsImpl), get_static_heap_bounds, ); + +struct MutexSyncOpsImpl; + +impl MutexSyncOps for MutexSyncOpsImpl { + fn signal(&self) { + get_static_heap_mutex_notification().signal(); + } + + fn wait(&self) { + get_static_heap_mutex_notification().wait(); + } +} diff --git a/crates/sel4-abstract-rc/Cargo.nix b/crates/sel4-abstract-rc/Cargo.nix new file mode 100644 index 000000000..599593c12 --- /dev/null +++ b/crates/sel4-abstract-rc/Cargo.nix @@ -0,0 +1,11 @@ +# +# Copyright 2024, Colias Group, LLC +# +# SPDX-License-Identifier: BSD-2-Clause +# + +{ mk }: + +mk { + package.name = "sel4-abstract-rc"; +} diff --git a/crates/sel4-abstract-rc/Cargo.toml b/crates/sel4-abstract-rc/Cargo.toml new file mode 100644 index 000000000..bf88087e1 --- /dev/null +++ b/crates/sel4-abstract-rc/Cargo.toml @@ -0,0 +1,17 @@ +# +# Copyright 2023, Colias Group, LLC +# +# SPDX-License-Identifier: BSD-2-Clause +# +# +# This file is generated from './Cargo.nix'. You can edit this file directly +# if you are not using this project's Cargo manifest management tools. +# See 'hacking/cargo-manifest-management/README.md' for more information. +# + +[package] +name = "sel4-abstract-rc" +version = "0.1.0" +authors = ["Nick Spinale "] +edition = "2021" +license = "BSD-2-Clause" diff --git a/crates/sel4-abstract-rc/src/lib.rs b/crates/sel4-abstract-rc/src/lib.rs new file mode 100644 index 000000000..d1790edfe --- /dev/null +++ b/crates/sel4-abstract-rc/src/lib.rs @@ -0,0 +1,35 @@ +// +// Copyright 2024, Colias Group, LLC +// +// SPDX-License-Identifier: BSD-2-Clause +// + +#![no_std] + +extern crate alloc; + +use alloc::rc::Rc; +use alloc::sync::Arc; +use core::ops::Deref; + +pub trait AbstractRcT { + type Rc: AbstractRc; +} + +pub struct RcT(()); + +impl AbstractRcT for RcT { + type Rc = Rc; +} + +pub struct ArcT(()); + +impl AbstractRcT for ArcT { + type Rc = Arc; +} + +pub trait AbstractRc: Deref + From + Clone {} + +impl AbstractRc for Rc {} + +impl AbstractRc for Arc {} diff --git a/crates/sel4-capdl-initializer/src/main.rs b/crates/sel4-capdl-initializer/src/main.rs index 8158617b3..2e0770713 100644 --- a/crates/sel4-capdl-initializer/src/main.rs +++ b/crates/sel4-capdl-initializer/src/main.rs @@ -113,16 +113,13 @@ fn static_heap_bounds() -> StaticHeapBounds { mod heap { use sel4_dlmalloc::{StaticDlmallocGlobalAlloc, StaticHeapBounds}; - use sel4_sync::{GenericRawMutex, PanickingMutexSyncOps}; + use sel4_sync::PanickingRawMutex; use super::static_heap_bounds; #[global_allocator] static GLOBAL_ALLOCATOR: StaticDlmallocGlobalAlloc< - GenericRawMutex, + PanickingRawMutex, fn() -> StaticHeapBounds, - > = StaticDlmallocGlobalAlloc::new( - GenericRawMutex::new(PanickingMutexSyncOps::new()), - static_heap_bounds, - ); + > = StaticDlmallocGlobalAlloc::new(PanickingRawMutex::new(), static_heap_bounds); } diff --git a/crates/sel4-microkit/src/heap.rs b/crates/sel4-microkit/src/heap.rs index 221033b6e..722d6c66d 100644 --- a/crates/sel4-microkit/src/heap.rs +++ b/crates/sel4-microkit/src/heap.rs @@ -23,12 +23,9 @@ macro_rules! declare_heap { #[global_allocator] static GLOBAL_ALLOCATOR: StaticDlmallocGlobalAlloc< - GenericRawMutex, + PanickingRawMutex, &'static StaticHeap<{ $size }>, - > = StaticDlmallocGlobalAlloc::new( - GenericRawMutex::new(PanickingMutexSyncOps::new()), - &STATIC_HEAP, - ); + > = StaticDlmallocGlobalAlloc::new(PanickingRawMutex::new(), &STATIC_HEAP); } } }; @@ -37,5 +34,5 @@ macro_rules! declare_heap { pub mod _private { pub use sel4_dlmalloc::{StaticDlmallocGlobalAlloc, StaticHeap}; - pub use sel4_sync::{GenericRawMutex, PanickingMutexSyncOps}; + pub use sel4_sync::PanickingRawMutex; } diff --git a/crates/sel4-root-task/src/heap.rs b/crates/sel4-root-task/src/heap.rs index 5fa6a153b..69c249cfb 100644 --- a/crates/sel4-root-task/src/heap.rs +++ b/crates/sel4-root-task/src/heap.rs @@ -44,14 +44,10 @@ macro_rules! declare_heap { #[global_allocator] static GLOBAL_ALLOCATOR: StaticDlmallocGlobalAlloc< - GenericRawMutex< - IndirectNotificationMutexSyncOps sel4::cap::Notification>, - >, + GenericRawMutex sel4::cap::Notification>, &'static StaticHeap<{ SIZE }>, > = StaticDlmallocGlobalAlloc::new( - GenericRawMutex::new(IndirectNotificationMutexSyncOps::new( - get_global_allocator_mutex_notification, - )), + GenericRawMutex::new(get_global_allocator_mutex_notification), &STATIC_HEAP, ); } @@ -62,7 +58,7 @@ macro_rules! declare_heap { pub mod _private { pub use sel4_dlmalloc::{StaticDlmallocGlobalAlloc, StaticHeap}; - pub use sel4_sync::{GenericRawMutex, IndirectNotificationMutexSyncOps}; + pub use sel4_sync::GenericRawMutex; pub use super::get_global_allocator_mutex_notification; } diff --git a/crates/sel4-shared-ring-buffer/smoltcp/Cargo.nix b/crates/sel4-shared-ring-buffer/smoltcp/Cargo.nix index 71de65be2..c94617542 100644 --- a/crates/sel4-shared-ring-buffer/smoltcp/Cargo.nix +++ b/crates/sel4-shared-ring-buffer/smoltcp/Cargo.nix @@ -9,9 +9,11 @@ mk { package.name = "sel4-shared-ring-buffer-smoltcp"; dependencies = { - inherit (versions) log; + inherit (versions) log lock_api; smoltcp = smoltcpWith []; inherit (localCrates) + sel4-abstract-rc + sel4-sync-trivial sel4-shared-ring-buffer sel4-shared-ring-buffer-bookkeeping sel4-bounce-buffer-allocator diff --git a/crates/sel4-shared-ring-buffer/smoltcp/Cargo.toml b/crates/sel4-shared-ring-buffer/smoltcp/Cargo.toml index b75aad137..99ab3ebcb 100644 --- a/crates/sel4-shared-ring-buffer/smoltcp/Cargo.toml +++ b/crates/sel4-shared-ring-buffer/smoltcp/Cargo.toml @@ -17,11 +17,14 @@ edition = "2021" license = "BSD-2-Clause" [dependencies] +lock_api = "0.4.12" log = "0.4.17" +sel4-abstract-rc = { path = "../../sel4-abstract-rc" } sel4-bounce-buffer-allocator = { path = "../../sel4-bounce-buffer-allocator" } sel4-externally-shared = { path = "../../sel4-externally-shared", features = ["unstable"] } sel4-shared-ring-buffer = { path = ".." } sel4-shared-ring-buffer-bookkeeping = { path = "../bookkeeping" } +sel4-sync-trivial = { path = "../../sel4-sync/trivial" } [dependencies.smoltcp] version = "0.10.0" diff --git a/crates/sel4-shared-ring-buffer/smoltcp/src/lib.rs b/crates/sel4-shared-ring-buffer/smoltcp/src/lib.rs index c389de489..47efe486c 100644 --- a/crates/sel4-shared-ring-buffer/smoltcp/src/lib.rs +++ b/crates/sel4-shared-ring-buffer/smoltcp/src/lib.rs @@ -8,26 +8,26 @@ extern crate alloc; -use alloc::rc::Rc; -use core::cell::RefCell; - +use lock_api::{Mutex, RawMutex}; use smoltcp::phy::{self, Device, DeviceCapabilities}; use smoltcp::time::Instant; +use sel4_abstract_rc::{AbstractRcT, RcT}; use sel4_bounce_buffer_allocator::{AbstractBounceBufferAllocator, BounceBufferAllocator}; use sel4_externally_shared::ExternallySharedRef; use sel4_shared_ring_buffer::{roles::Provide, RingBuffers}; +use sel4_sync_trivial::UnsyncPanickingRawMutex; mod inner; pub use inner::{Error, PeerMisbehaviorError}; use inner::{Inner, RxBufferIndex, TxBufferIndex}; -pub struct DeviceImpl { - inner: Rc>>, +pub struct DeviceImpl { + inner: P::Rc>>, } -impl Clone for DeviceImpl { +impl Clone for DeviceImpl { fn clone(&self) -> Self { Self { inner: self.inner.clone(), @@ -35,8 +35,9 @@ impl Clone for DeviceImpl { } } -impl DeviceImpl { +impl DeviceImpl { pub fn new( + raw_mutex: R, dma_region: ExternallySharedRef<'static, [u8]>, bounce_buffer_allocator: BounceBufferAllocator, rx_ring_buffers: RingBuffers<'static, Provide, fn()>, @@ -46,42 +47,45 @@ impl DeviceImpl { caps: DeviceCapabilities, ) -> Result { Ok(Self { - inner: Rc::new(RefCell::new(Inner::new( - dma_region, - bounce_buffer_allocator, - rx_ring_buffers, - tx_ring_buffers, - num_rx_buffers, - rx_buffer_size, - caps, - )?)), + inner: P::Rc::from(Mutex::from_raw( + raw_mutex, + Inner::new( + dma_region, + bounce_buffer_allocator, + rx_ring_buffers, + tx_ring_buffers, + num_rx_buffers, + rx_buffer_size, + caps, + )?, + )), }) } - fn inner(&self) -> &Rc>> { + fn inner(&self) -> &P::Rc>> { &self.inner } pub fn poll(&self) -> bool { - self.inner().borrow_mut().poll().unwrap() + self.inner().lock().poll().unwrap() } pub fn can_receive(&self) -> bool { - self.inner().borrow_mut().can_receive() + self.inner().lock().can_receive() } pub fn can_transmit(&self) -> bool { - self.inner().borrow_mut().can_transmit() + self.inner().lock().can_transmit() } - fn new_rx_token(&self, rx_buffer: RxBufferIndex) -> RxToken { + fn new_rx_token(&self, rx_buffer: RxBufferIndex) -> RxToken { RxToken { buffer: rx_buffer, shared: self.clone(), } } - fn new_tx_token(&self, tx_buffer: TxBufferIndex) -> TxToken { + fn new_tx_token(&self, tx_buffer: TxBufferIndex) -> TxToken { TxToken { buffer: tx_buffer, shared: self.clone(), @@ -89,83 +93,76 @@ impl DeviceImpl { } } -impl Device for DeviceImpl { - type RxToken<'a> = RxToken where A: 'a; - type TxToken<'a> = TxToken where A: 'a; +impl Device for DeviceImpl { + type RxToken<'a> = RxToken where A: 'a, R: 'a, P: 'a; + type TxToken<'a> = TxToken where A: 'a, R: 'a, P: 'a; fn capabilities(&self) -> DeviceCapabilities { - self.inner().borrow().caps().clone() + self.inner().lock().caps().clone() } fn receive(&mut self, _timestamp: Instant) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> { self.inner() - .borrow_mut() + .lock() .receive() .map(|(rx_ix, tx_ix)| (self.new_rx_token(rx_ix), self.new_tx_token(tx_ix))) } fn transmit(&mut self, _timestamp: Instant) -> Option> { self.inner() - .borrow_mut() + .lock() .transmit() .map(|ix| self.new_tx_token(ix)) } } -pub struct RxToken { +pub struct RxToken { buffer: RxBufferIndex, - shared: DeviceImpl, + shared: DeviceImpl, } -impl phy::RxToken for RxToken { - fn consume(self, f: F) -> R +impl phy::RxToken + for RxToken +{ + fn consume(self, f: F) -> T where - F: FnOnce(&mut [u8]) -> R, + F: FnOnce(&mut [u8]) -> T, { - let mut ptr = self - .shared - .inner() - .borrow_mut() - .consume_rx_start(self.buffer); + let mut ptr = self.shared.inner().lock().consume_rx_start(self.buffer); let r = f(unsafe { ptr.as_mut() }); - self.shared - .inner() - .borrow_mut() - .consume_rx_finish(self.buffer); + self.shared.inner().lock().consume_rx_finish(self.buffer); r } } -impl Drop for RxToken { +impl Drop for RxToken { fn drop(&mut self) { - self.shared - .inner() - .borrow_mut() - .drop_rx(self.buffer) - .unwrap() + self.shared.inner().lock().drop_rx(self.buffer).unwrap() } } -pub struct TxToken { +pub struct TxToken { buffer: TxBufferIndex, - shared: DeviceImpl, + shared: DeviceImpl, } -impl phy::TxToken for TxToken { - fn consume(self, len: usize, f: F) -> R +impl phy::TxToken + for TxToken +{ + fn consume(self, len: usize, f: F) -> T where - F: FnOnce(&mut [u8]) -> R, + F: FnOnce(&mut [u8]) -> T, { self.shared .inner() - .borrow_mut() + .lock() .consume_tx(self.buffer, len, f) .unwrap() } } -impl Drop for TxToken { +impl Drop for TxToken { fn drop(&mut self) { - self.shared.inner().borrow_mut().drop_tx(self.buffer) + self.shared.inner().lock().drop_tx(self.buffer) } } diff --git a/crates/sel4-sync/Cargo.nix b/crates/sel4-sync/Cargo.nix index ad9706cee..537f90dc3 100644 --- a/crates/sel4-sync/Cargo.nix +++ b/crates/sel4-sync/Cargo.nix @@ -17,6 +17,7 @@ mk rec { inherit (localCrates) sel4 sel4-immediate-sync-once-cell + sel4-sync-trivial ; }; } diff --git a/crates/sel4-sync/Cargo.toml b/crates/sel4-sync/Cargo.toml index fe344833f..5624d6604 100644 --- a/crates/sel4-sync/Cargo.toml +++ b/crates/sel4-sync/Cargo.toml @@ -20,3 +20,4 @@ license = "MIT" lock_api = "0.4.12" sel4 = { path = "../sel4" } sel4-immediate-sync-once-cell = { path = "../sel4-immediate-sync-once-cell" } +sel4-sync-trivial = { path = "trivial" } diff --git a/crates/sel4-sync/src/lib.rs b/crates/sel4-sync/src/lib.rs index 656cdccba..dbdfdbe67 100644 --- a/crates/sel4-sync/src/lib.rs +++ b/crates/sel4-sync/src/lib.rs @@ -8,10 +8,11 @@ pub use lock_api; +pub use sel4_sync_trivial::*; + mod mutex; pub use mutex::{ - AbstractMutexSyncOps, DeferredNotificationMutexSyncOps, GenericRawMutex, - IndirectNotificationMutexSyncOps, MutexSyncOps, MutexSyncOpsWithInteriorMutability, - MutexSyncOpsWithNotification, PanickingMutexSyncOps, PanickingRawMutex, + DeferredNotificationMutexSyncOps, GenericRawMutex, MutexSyncOps, + MutexSyncOpsWithInteriorMutability, MutexSyncOpsWithNotification, }; diff --git a/crates/sel4-sync/src/mutex.rs b/crates/sel4-sync/src/mutex.rs index 301855f0e..bbeb260e2 100644 --- a/crates/sel4-sync/src/mutex.rs +++ b/crates/sel4-sync/src/mutex.rs @@ -5,38 +5,10 @@ // SPDX-License-Identifier: MIT // -use core::sync::atomic::{fence, AtomicBool, AtomicIsize, Ordering}; +use core::sync::atomic::{fence, AtomicIsize, Ordering}; use sel4_immediate_sync_once_cell::ImmediateSyncOnceCell; -pub struct PanickingRawMutex { - locked: AtomicBool, -} - -unsafe impl lock_api::RawMutex for PanickingRawMutex { - type GuardMarker = lock_api::GuardNoSend; // TODO - - #[allow(clippy::declare_interior_mutable_const)] - const INIT: Self = Self { - locked: AtomicBool::new(false), - }; - - fn lock(&self) { - if !self.try_lock() { - panic!("lock contention") - } - } - - fn try_lock(&self) -> bool { - let was_locked = self.locked.swap(true, Ordering::Acquire); - !was_locked - } - - unsafe fn unlock(&self) { - self.locked.store(false, Ordering::Release) - } -} - pub struct GenericRawMutex { sync_ops: O, value: AtomicIsize, @@ -51,12 +23,24 @@ impl GenericRawMutex { } } +pub trait MutexSyncOpsWithInteriorMutability { + type ModifyInput; + type ModifyOutput; + + fn modify(&self, input: Self::ModifyInput) -> Self::ModifyOutput; +} + impl GenericRawMutex { pub fn modify(&self, input: O::ModifyInput) -> O::ModifyOutput { self.sync_ops.modify(input) } } +pub trait MutexSyncOps { + fn signal(&self); + fn wait(&self); +} + unsafe impl lock_api::RawMutex for GenericRawMutex { type GuardMarker = lock_api::GuardNoSend; // TODO @@ -82,18 +66,6 @@ unsafe impl lock_api::RawMutex for GenericRawMutex { } } -pub trait MutexSyncOps { - fn signal(&self); - fn wait(&self); -} - -pub trait MutexSyncOpsWithInteriorMutability { - type ModifyInput; - type ModifyOutput; - - fn modify(&self, input: Self::ModifyInput) -> Self::ModifyOutput; -} - pub trait MutexSyncOpsWithNotification { fn notification(&self) -> sel4::cap::Notification; } @@ -114,6 +86,12 @@ impl MutexSyncOpsWithNotification for sel4::cap::Notification { } } +impl sel4::cap::Notification> MutexSyncOpsWithNotification for F { + fn notification(&self) -> sel4::cap::Notification { + (self)() + } +} + pub struct DeferredNotificationMutexSyncOps { inner: ImmediateSyncOnceCell, } @@ -146,66 +124,3 @@ impl MutexSyncOpsWithInteriorMutability for DeferredNotificationMutexSyncOps { self.inner.set(input).unwrap() } } - -pub struct IndirectNotificationMutexSyncOps { - get_notification: T, -} - -impl sel4::cap::Notification> IndirectNotificationMutexSyncOps { - pub const fn new(get_notification: T) -> Self { - Self { get_notification } - } -} - -impl sel4::cap::Notification> MutexSyncOpsWithNotification - for IndirectNotificationMutexSyncOps -{ - fn notification(&self) -> sel4::cap::Notification { - (self.get_notification)() - } -} - -pub struct AbstractMutexSyncOps { - pub signal: T, - pub wait: U, -} - -impl AbstractMutexSyncOps { - pub const fn new(signal: T, wait: U) -> Self { - Self { signal, wait } - } -} - -impl MutexSyncOps for AbstractMutexSyncOps { - fn signal(&self) { - (self.signal)() - } - - fn wait(&self) { - (self.wait)() - } -} - -pub struct PanickingMutexSyncOps(()); - -impl PanickingMutexSyncOps { - pub const fn new() -> Self { - Self(()) - } -} - -impl Default for PanickingMutexSyncOps { - fn default() -> Self { - Self::new() - } -} - -impl MutexSyncOps for PanickingMutexSyncOps { - fn signal(&self) { - panic!("unexpected contention: signal") - } - - fn wait(&self) { - panic!("unexpected contention: wait") - } -} diff --git a/crates/sel4-sync/trivial/Cargo.nix b/crates/sel4-sync/trivial/Cargo.nix new file mode 100644 index 000000000..1e59fd716 --- /dev/null +++ b/crates/sel4-sync/trivial/Cargo.nix @@ -0,0 +1,14 @@ +# +# Copyright 2023, Colias Group, LLC +# +# SPDX-License-Identifier: BSD-2-Clause +# + +{ mk, versions }: + +mk { + package.name = "sel4-sync-trivial"; + dependencies = { + inherit (versions) lock_api; + }; +} diff --git a/crates/sel4-sync/trivial/Cargo.toml b/crates/sel4-sync/trivial/Cargo.toml new file mode 100644 index 000000000..5f256f946 --- /dev/null +++ b/crates/sel4-sync/trivial/Cargo.toml @@ -0,0 +1,20 @@ +# +# Copyright 2023, Colias Group, LLC +# +# SPDX-License-Identifier: BSD-2-Clause +# +# +# This file is generated from './Cargo.nix'. You can edit this file directly +# if you are not using this project's Cargo manifest management tools. +# See 'hacking/cargo-manifest-management/README.md' for more information. +# + +[package] +name = "sel4-sync-trivial" +version = "0.1.0" +authors = ["Nick Spinale "] +edition = "2021" +license = "BSD-2-Clause" + +[dependencies] +lock_api = "0.4.12" diff --git a/crates/sel4-sync/trivial/src/lib.rs b/crates/sel4-sync/trivial/src/lib.rs new file mode 100644 index 000000000..4b85309f3 --- /dev/null +++ b/crates/sel4-sync/trivial/src/lib.rs @@ -0,0 +1,90 @@ +// +// Copyright 2024, Colias Group, LLC +// +// SPDX-License-Identifier: BSD-2-Clause +// + +#![no_std] + +use core::cell::Cell; +use core::sync::atomic::{AtomicBool, Ordering}; + +pub struct PanickingRawMutex { + locked: AtomicBool, +} + +impl PanickingRawMutex { + pub const fn new() -> Self { + Self { + locked: AtomicBool::new(false), + } + } +} + +impl Default for PanickingRawMutex { + fn default() -> Self { + Self::new() + } +} + +unsafe impl lock_api::RawMutex for PanickingRawMutex { + type GuardMarker = lock_api::GuardNoSend; // TODO + + #[allow(clippy::declare_interior_mutable_const)] + const INIT: Self = Self::new(); + + fn lock(&self) { + if !self.try_lock() { + panic!("lock contention") + } + } + + fn try_lock(&self) -> bool { + let was_locked = self.locked.swap(true, Ordering::Acquire); + !was_locked + } + + unsafe fn unlock(&self) { + self.locked.store(false, Ordering::Release) + } +} + +pub struct UnsyncPanickingRawMutex { + locked: Cell, +} + +impl UnsyncPanickingRawMutex { + pub const fn new() -> Self { + Self { + locked: Cell::new(false), + } + } +} + +impl Default for UnsyncPanickingRawMutex { + fn default() -> Self { + Self::new() + } +} + +unsafe impl lock_api::RawMutex for UnsyncPanickingRawMutex { + type GuardMarker = lock_api::GuardNoSend; // TODO + + #[allow(clippy::declare_interior_mutable_const)] + const INIT: Self = Self::new(); + + fn lock(&self) { + if !self.try_lock() { + panic!("lock contention") + } + } + + fn try_lock(&self) -> bool { + let was_locked = self.locked.replace(true); + !was_locked + } + + unsafe fn unlock(&self) { + self.locked.set(false) + } +}