diff --git a/Cargo.lock b/Cargo.lock index bcb0a8424..a6ea63422 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1746,6 +1746,7 @@ dependencies = [ "sel4-microkit", "sel4-microkit-message", "sel4-microkit-message-types", + "sel4-one-ref-cell", "sel4-platform-info", "sel4-root-task", "sel4-shared-ring-buffer", @@ -3256,6 +3257,10 @@ dependencies = [ "sel4-panicking-env", ] +[[package]] +name = "sel4-one-ref-cell" +version = "0.1.0" + [[package]] name = "sel4-panicking" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index 25f5f393a..ef60b5aca 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -95,6 +95,7 @@ members = [ "crates/sel4-microkit/message", "crates/sel4-microkit/message/types", "crates/sel4-newlib", + "crates/sel4-one-ref-cell", "crates/sel4-panicking", "crates/sel4-panicking/env", "crates/sel4-platform-info", diff --git a/crates/private/meta/Cargo.toml b/crates/private/meta/Cargo.toml index 7caabdaf6..8e658be45 100644 --- a/crates/private/meta/Cargo.toml +++ b/crates/private/meta/Cargo.toml @@ -28,6 +28,7 @@ sel4-logging = { path = "../../sel4-logging" } sel4-microkit = { path = "../../sel4-microkit", features = ["full"], optional = true } sel4-microkit-message = { path = "../../sel4-microkit/message", optional = true } sel4-microkit-message-types = { path = "../../sel4-microkit/message/types", optional = true } +sel4-one-ref-cell = { path = "../../sel4-one-ref-cell" } sel4-root-task = { path = "../../sel4-root-task", features = ["full"], optional = true } sel4-shared-ring-buffer = { path = "../../sel4-shared-ring-buffer" } sel4-shared-ring-buffer-block-io = { path = "../../sel4-shared-ring-buffer/block-io" } diff --git a/crates/private/meta/src/lib.rs b/crates/private/meta/src/lib.rs index e0b6f1175..9284c8531 100644 --- a/crates/private/meta/src/lib.rs +++ b/crates/private/meta/src/lib.rs @@ -76,6 +76,7 @@ definitely! { sel4 sel4_async_block_io sel4_async_block_io_cpiofs + sel4_async_block_io_fat sel4_async_network sel4_async_request_statuses sel4_async_single_threaded_executor @@ -86,6 +87,7 @@ definitely! { sel4_immediate_sync_once_cell sel4_immutable_cell sel4_logging + sel4_one_ref_cell sel4_shared_ring_buffer sel4_shared_ring_buffer_block_io sel4_shared_ring_buffer_block_io_types diff --git a/crates/sel4-immediate-sync-once-cell/src/lib.rs b/crates/sel4-immediate-sync-once-cell/src/lib.rs index 7ed61bdd6..f9a18f497 100644 --- a/crates/sel4-immediate-sync-once-cell/src/lib.rs +++ b/crates/sel4-immediate-sync-once-cell/src/lib.rs @@ -10,6 +10,12 @@ pub struct ImmediateSyncOnceCell { inner: SyncUnsafeCell>, } +impl Default for ImmediateSyncOnceCell { + fn default() -> Self { + Self::new() + } +} + impl ImmediateSyncOnceCell { pub const fn new() -> Self { Self { diff --git a/crates/sel4-immutable-cell/src/lib.rs b/crates/sel4-immutable-cell/src/lib.rs index 25288d1dd..83bc18188 100644 --- a/crates/sel4-immutable-cell/src/lib.rs +++ b/crates/sel4-immutable-cell/src/lib.rs @@ -9,14 +9,14 @@ pub struct ImmutableCell { } impl Default for ImmutableCell { - fn default() -> ImmutableCell { - ImmutableCell::new(Default::default()) + fn default() -> Self { + Self::new(Default::default()) } } impl From for ImmutableCell { - fn from(t: T) -> ImmutableCell { - ImmutableCell::new(t) + fn from(t: T) -> Self { + Self::new(t) } } diff --git a/crates/sel4-one-ref-cell/Cargo.toml b/crates/sel4-one-ref-cell/Cargo.toml new file mode 100644 index 000000000..e465f7f46 --- /dev/null +++ b/crates/sel4-one-ref-cell/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "sel4-one-ref-cell" +version = "0.1.0" +authors = ["Nick Spinale "] +edition = "2021" +license = "BSD-2-Clause" diff --git a/crates/sel4-one-ref-cell/src/lib.rs b/crates/sel4-one-ref-cell/src/lib.rs new file mode 100644 index 000000000..ac64a65c8 --- /dev/null +++ b/crates/sel4-one-ref-cell/src/lib.rs @@ -0,0 +1,45 @@ +#![no_std] +#![feature(sync_unsafe_cell)] + +use core::cell::SyncUnsafeCell; +use core::sync::atomic::{AtomicBool, Ordering}; + +pub struct OneRefCell { + taken: AtomicBool, + value: SyncUnsafeCell, +} + +impl Default for OneRefCell { + fn default() -> Self { + Self::new(Default::default()) + } +} + +impl From for OneRefCell { + fn from(t: T) -> Self { + Self::new(t) + } +} + +impl OneRefCell { + pub const fn new(value: T) -> Self { + Self { + taken: AtomicBool::new(false), + value: SyncUnsafeCell::new(value), + } + } + + pub fn take(&self) -> Result<&mut T, Error> { + if self.taken.swap(true, Ordering::SeqCst) { + Err(Error::AlreadyTaken) + } else { + let ptr = self.value.get(); + Ok(unsafe { ptr.as_mut() }.unwrap()) + } + } +} + +#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] +pub enum Error { + AlreadyTaken, +} diff --git a/hacking/cargo-manifest-sources/crates/private/meta/crate.nix b/hacking/cargo-manifest-sources/crates/private/meta/crate.nix index 31948deb6..7d4cf626c 100644 --- a/hacking/cargo-manifest-sources/crates/private/meta/crate.nix +++ b/hacking/cargo-manifest-sources/crates/private/meta/crate.nix @@ -25,6 +25,7 @@ mk { sel4-immediate-sync-once-cell sel4-immutable-cell sel4-logging + sel4-one-ref-cell sel4-shared-ring-buffer sel4-shared-ring-buffer-block-io sel4-shared-ring-buffer-block-io-types diff --git a/hacking/cargo-manifest-sources/crates/sel4-one-ref-cell/crate.nix b/hacking/cargo-manifest-sources/crates/sel4-one-ref-cell/crate.nix new file mode 100644 index 000000000..c379c9907 --- /dev/null +++ b/hacking/cargo-manifest-sources/crates/sel4-one-ref-cell/crate.nix @@ -0,0 +1,5 @@ +{ mk }: + +mk { + package.name = "sel4-one-ref-cell"; +}