From b574c6990b0776d6844070fef6ac1b3f32d566e3 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 7 Feb 2025 15:56:03 +0100 Subject: [PATCH] use static cell instead of custom struct --- .../stm32h7-nucleo-rtic/Cargo.lock | 10 ++ satrs/Cargo.toml | 1 + satrs/src/pool.rs | 133 ++++++------------ 3 files changed, 54 insertions(+), 90 deletions(-) diff --git a/embedded-examples/stm32h7-nucleo-rtic/Cargo.lock b/embedded-examples/stm32h7-nucleo-rtic/Cargo.lock index 38152e6..aa4b9fb 100644 --- a/embedded-examples/stm32h7-nucleo-rtic/Cargo.lock +++ b/embedded-examples/stm32h7-nucleo-rtic/Cargo.lock @@ -631,6 +631,7 @@ dependencies = [ "satrs-shared", "smallvec", "spacepackets", + "static_cell", "thiserror", ] @@ -720,6 +721,15 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +[[package]] +name = "static_cell" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89b0684884a883431282db1e4343f34afc2ff6996fe1f4a1664519b66e14c1e" +dependencies = [ + "portable-atomic", +] + [[package]] name = "stm32h7" version = "0.15.1" diff --git a/satrs/Cargo.toml b/satrs/Cargo.toml index c333c71..c438269 100644 --- a/satrs/Cargo.toml +++ b/satrs/Cargo.toml @@ -18,6 +18,7 @@ paste = "1" derive-new = ">=0.6, <=0.7" smallvec = "1" crc = "3" +static_cell = "2" [dependencies.satrs-shared] version = ">=0.1.3, <=0.2" diff --git a/satrs/src/pool.rs b/satrs/src/pool.rs index 86e4b75..1f04d8c 100644 --- a/satrs/src/pool.rs +++ b/satrs/src/pool.rs @@ -378,74 +378,27 @@ pub struct SubpoolConfig { #[cfg(feature = "heapless")] pub mod heapless_mod { use super::*; - use core::cell::UnsafeCell; - use core::sync::atomic::{AtomicBool, Ordering}; #[derive(Debug, Copy, Clone, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct PoolIsFull; - #[derive(Debug)] - pub struct UnsafeCellBufWrapper { - val: UnsafeCell, - once: AtomicBool, - } - // `Sync` is required because `UnsafeCell` is not `Sync` by default. - // This is safe as long as access is manually synchronized. - unsafe impl Sync for UnsafeCellBufWrapper {} - - impl UnsafeCellBufWrapper { - /// Creates a new wrapper around an arbitrary value which should be [Sync]. - pub const fn new(v: T) -> Self { - unsafe { Self::new_unchecked(v) } - } - } - - impl UnsafeCellBufWrapper { - /// Creates a new wrapper around a buffer. - /// - /// # Safety - /// - /// Currently, the [Sync] trait is implemented for all T and ignores the usual [Sync] bound - /// on T. This API should only be called for declaring byte buffers statically or if T is - /// known to be [Sync]. You can use [new] to let the compiler do the [Sync] check. - pub const unsafe fn new_unchecked(v: T) -> Self { - Self { - val: UnsafeCell::new(v), - once: AtomicBool::new(false), - } - } - - /// Retrieves a mutable reference to the internal value once. - /// - /// All subsequent calls return None. - pub fn get_mut(&self) -> Option<&mut T> { - if self.once.load(Ordering::Relaxed) { - return None; - } - // Safety: We ensure that this is only done once with an [AtomicBool]. - let mut_ref = unsafe { &mut *self.val.get() }; - self.once.store(true, Ordering::Relaxed); - Some(mut_ref) - } - } - /// Helper macro to generate static buffers for the [crate::pool::StaticHeaplessMemoryPool]. #[macro_export] macro_rules! static_subpool { ($pool_name: ident, $sizes_list_name: ident, $num_blocks: expr, $block_size: expr) => { - static $pool_name: $crate::pool::UnsafeCellBufWrapper<[u8; $num_blocks * $block_size]> = - $crate::pool::UnsafeCellBufWrapper::new([0; $num_blocks * $block_size]); - static $sizes_list_name: $crate::pool::UnsafeCellBufWrapper<[usize; $num_blocks]> = - $crate::pool::UnsafeCellBufWrapper::new([$crate::pool::STORE_FREE; $num_blocks]); + static $pool_name: static_cell::ConstStaticCell<[u8; $num_blocks * $block_size]> = + static_cell::ConstStaticCell::new([0; $num_blocks * $block_size]); + static $sizes_list_name: static_cell::ConstStaticCell<[usize; $num_blocks]> = + static_cell::ConstStaticCell::new([$crate::pool::STORE_FREE; $num_blocks]); }; ($pool_name: ident, $sizes_list_name: ident, $num_blocks: expr, $block_size: expr, $meta_data: meta) => { #[$meta_data] - static $pool_name: $crate::pool::UnsafeCellBufWrapper<[u8; $num_blocks * $block_size]> = - $crate::pool::UnsafeCellBufWrapper::new([0; $num_blocks * $block_size]); + static $pool_name: static_cell::ConstStaticCell<[u8; $num_blocks * $block_size]> = + static_cell::ConstStaticCell::new([0; $num_blocks * $block_size]); #[$meta_data] - static $sizes_list_name: $crate::pool::UnsafeCellBufWrapper<[usize; $num_blocks]> = - $crate::pool::UnsafeCellBufWrapper::new([$crate::pool::STORE_FREE; $num_blocks]); + static $sizes_list_name: static_cell::ConstStaticCell<[usize; $num_blocks]> = + static_cell::ConstStaticCell::new([$crate::pool::STORE_FREE; $num_blocks]); }; } @@ -482,14 +435,14 @@ pub mod heapless_mod { /// /// let mut mem_pool: StaticHeaplessMemoryPool<2> = StaticHeaplessMemoryPool::new(true); /// mem_pool.grow( - /// SUBPOOL_SMALL.get_mut().unwrap(), - /// SUBPOOL_SMALL_SIZES.get_mut().unwrap(), + /// SUBPOOL_SMALL.take(), + /// SUBPOOL_SMALL_SIZES.take(), /// SUBPOOL_SMALL_NUM_BLOCKS, /// false /// ).unwrap(); /// mem_pool.grow( - /// SUBPOOL_LARGE.get_mut().unwrap(), - /// SUBPOOL_LARGE_SIZES.get_mut().unwrap(), + /// SUBPOOL_LARGE.take(), + /// SUBPOOL_LARGE_SIZES.take(), /// SUBPOOL_LARGE_NUM_BLOCKS, /// false /// ).unwrap(); @@ -1639,9 +1592,9 @@ mod tests { const SUBPOOL_1_BLOCK_SIZE: usize = 4; const SUBPOOL_1_NUM_ELEMENTS: u16 = 4; - static SUBPOOL_1: UnsafeCellBufWrapper< + static SUBPOOL_1: static_cell::ConstStaticCell< [u8; SUBPOOL_1_NUM_ELEMENTS as usize * SUBPOOL_1_BLOCK_SIZE], - > = UnsafeCellBufWrapper::new([0; SUBPOOL_1_NUM_ELEMENTS as usize * SUBPOOL_1_BLOCK_SIZE]); + > = static_cell::ConstStaticCell::new([0; SUBPOOL_1_NUM_ELEMENTS as usize * SUBPOOL_1_BLOCK_SIZE]); static SUBPOOL_1_SIZES: Mutex> = Mutex::new(UnsafeCell::new( @@ -1650,11 +1603,11 @@ mod tests { const SUBPOOL_2_NUM_ELEMENTS: u16 = 2; const SUBPOOL_2_BLOCK_SIZE: usize = 8; - static SUBPOOL_2: UnsafeCellBufWrapper< + static SUBPOOL_2: static_cell::ConstStaticCell< [u8; SUBPOOL_2_NUM_ELEMENTS as usize * SUBPOOL_2_BLOCK_SIZE], - > = UnsafeCellBufWrapper::new([0; SUBPOOL_2_NUM_ELEMENTS as usize * SUBPOOL_2_BLOCK_SIZE]); - static SUBPOOL_2_SIZES: UnsafeCellBufWrapper<[usize; SUBPOOL_2_NUM_ELEMENTS as usize]> = - UnsafeCellBufWrapper::new([STORE_FREE; SUBPOOL_2_NUM_ELEMENTS as usize]); + > = static_cell::ConstStaticCell::new([0; SUBPOOL_2_NUM_ELEMENTS as usize * SUBPOOL_2_BLOCK_SIZE]); + static SUBPOOL_2_SIZES: static_cell::ConstStaticCell<[usize; SUBPOOL_2_NUM_ELEMENTS as usize]> = + static_cell::ConstStaticCell::new([STORE_FREE; SUBPOOL_2_NUM_ELEMENTS as usize]); const SUBPOOL_3_NUM_ELEMENTS: u16 = 1; const SUBPOOL_3_BLOCK_SIZE: usize = 16; @@ -1697,7 +1650,7 @@ mod tests { StaticHeaplessMemoryPool::new(false); assert!(heapless_pool .grow( - SUBPOOL_1.get_mut().unwrap(), + SUBPOOL_1.take(), unsafe { &mut *SUBPOOL_1_SIZES.lock().unwrap().get() }, SUBPOOL_1_NUM_ELEMENTS, true @@ -1705,16 +1658,16 @@ mod tests { .is_ok()); assert!(heapless_pool .grow( - SUBPOOL_2.get_mut().unwrap(), - SUBPOOL_2_SIZES.get_mut().unwrap(), + SUBPOOL_2.take(), + SUBPOOL_2_SIZES.take(), SUBPOOL_2_NUM_ELEMENTS, true ) .is_ok()); assert!(heapless_pool .grow( - SUBPOOL_3.get_mut().unwrap(), - SUBPOOL_3_SIZES.get_mut().unwrap(), + SUBPOOL_3.take(), + SUBPOOL_3_SIZES.take(), SUBPOOL_3_NUM_ELEMENTS, true ) @@ -1836,16 +1789,16 @@ mod tests { StaticHeaplessMemoryPool::new(true); assert!(heapless_pool .grow( - SUBPOOL_2.get_mut().unwrap(), - SUBPOOL_2_SIZES.get_mut().unwrap(), + SUBPOOL_2.take(), + SUBPOOL_2_SIZES.take(), SUBPOOL_2_NUM_ELEMENTS, true ) .is_ok()); assert!(heapless_pool .grow( - SUBPOOL_4.get_mut().unwrap(), - SUBPOOL_4_SIZES.get_mut().unwrap(), + SUBPOOL_4.take(), + SUBPOOL_4_SIZES.take(), SUBPOOL_4_NUM_ELEMENTS, true ) @@ -1859,16 +1812,16 @@ mod tests { StaticHeaplessMemoryPool::new(true); assert!(heapless_pool .grow( - SUBPOOL_5.get_mut().unwrap(), - SUBPOOL_5_SIZES.get_mut().unwrap(), + SUBPOOL_5.take(), + SUBPOOL_5_SIZES.take(), SUBPOOL_5_NUM_ELEMENTS, true ) .is_ok()); assert!(heapless_pool .grow( - SUBPOOL_3.get_mut().unwrap(), - SUBPOOL_3_SIZES.get_mut().unwrap(), + SUBPOOL_3.take(), + SUBPOOL_3_SIZES.take(), SUBPOOL_3_NUM_ELEMENTS, true ) @@ -1882,24 +1835,24 @@ mod tests { StaticHeaplessMemoryPool::new(true); assert!(heapless_pool .grow( - SUBPOOL_5.get_mut().unwrap(), - SUBPOOL_5_SIZES.get_mut().unwrap(), + SUBPOOL_5.take(), + SUBPOOL_5_SIZES.take(), SUBPOOL_5_NUM_ELEMENTS, true ) .is_ok()); assert!(heapless_pool .grow( - SUBPOOL_6.get_mut().unwrap(), - SUBPOOL_6_SIZES.get_mut().unwrap(), + SUBPOOL_6.take(), + SUBPOOL_6_SIZES.take(), SUBPOOL_6_NUM_ELEMENTS, true ) .is_ok()); assert!(heapless_pool .grow( - SUBPOOL_3.get_mut().unwrap(), - SUBPOOL_3_SIZES.get_mut().unwrap(), + SUBPOOL_3.take(), + SUBPOOL_3_SIZES.take(), SUBPOOL_3_NUM_ELEMENTS, true ) @@ -1913,24 +1866,24 @@ mod tests { StaticHeaplessMemoryPool::new(true); assert!(heapless_pool .grow( - SUBPOOL_5.get_mut().unwrap(), - SUBPOOL_5_SIZES.get_mut().unwrap(), + SUBPOOL_5.take(), + SUBPOOL_5_SIZES.take(), SUBPOOL_5_NUM_ELEMENTS, true ) .is_ok()); assert!(heapless_pool .grow( - SUBPOOL_6.get_mut().unwrap(), - SUBPOOL_6_SIZES.get_mut().unwrap(), + SUBPOOL_6.take(), + SUBPOOL_6_SIZES.take(), SUBPOOL_6_NUM_ELEMENTS, true ) .is_ok()); assert!(heapless_pool .grow( - SUBPOOL_3.get_mut().unwrap(), - SUBPOOL_3_SIZES.get_mut().unwrap(), + SUBPOOL_3.take(), + SUBPOOL_3_SIZES.take(), SUBPOOL_3_NUM_ELEMENTS, true )