diff --git a/Cargo.lock b/Cargo.lock index f3582ff8..4faada26 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -754,8 +754,11 @@ dependencies = [ name = "iceoryx2-fal" version = "0.4.1" dependencies = [ + "iceoryx2-bb-elementary", + "iceoryx2-bb-log", "iceoryx2-bb-system-types", "iceoryx2-cal", + "iceoryx2-pal-concurrency-sync", ] [[package]] diff --git a/iceoryx2-fal/Cargo.toml b/iceoryx2-fal/Cargo.toml index cbaf8219..8f38a04d 100644 --- a/iceoryx2-fal/Cargo.toml +++ b/iceoryx2-fal/Cargo.toml @@ -13,3 +13,6 @@ version = { workspace = true } [dependencies] iceoryx2-cal = { workspace = true } iceoryx2-bb-system-types = { workspace = true } +iceoryx2-bb-elementary = { workspace = true } +iceoryx2-bb-log = { workspace = true } +iceoryx2-pal-concurrency-sync = { workspace = true } diff --git a/iceoryx2-fal/src/resizable_shared_memory.rs b/iceoryx2-fal/src/resizable_shared_memory.rs index de36d9eb..567cb7dc 100644 --- a/iceoryx2-fal/src/resizable_shared_memory.rs +++ b/iceoryx2-fal/src/resizable_shared_memory.rs @@ -11,46 +11,124 @@ // SPDX-License-Identifier: Apache-2.0 OR MIT use std::alloc::Layout; -use std::collections::VecDeque; +use std::fmt::Debug; use std::time::Duration; +use iceoryx2_bb_elementary::CallbackProgression; +use iceoryx2_bb_log::fail; use iceoryx2_bb_system_types::file_name::FileName; -use iceoryx2_cal::shared_memory::{SharedMemory, SharedMemoryCreateError, SharedMemoryOpenError}; +use iceoryx2_cal::named_concept::*; +use iceoryx2_cal::shared_memory::{ + SharedMemory, SharedMemoryBuilder, SharedMemoryCreateError, SharedMemoryOpenError, ShmPointer, +}; use iceoryx2_cal::shm_allocator::pool_allocator::PoolAllocator; -use iceoryx2_cal::shm_allocator::ShmAllocator; +use iceoryx2_cal::shm_allocator::{PointerOffset, ShmAllocationError}; + +#[derive(Debug)] +pub struct UniqueIndexVector { + data: Vec, + idx_to_data: Vec, + current_idx: usize, +} + +impl UniqueIndexVector { + pub fn new() -> Self { + Self { + data: vec![], + idx_to_data: vec![], + current_idx: 0, + } + } + + pub fn push(&mut self, value: T) -> usize { + todo!() + } + + pub fn write_at(&mut self, value: T, index: usize) {} + + pub fn remove(&mut self, index: usize) {} + + pub fn get(&self, index: usize) -> &T { + todo!() + } + + pub fn get_mut(&mut self, index: usize) -> &mut T { + todo!() + } +} + +impl From<[T; N]> for UniqueIndexVector { + fn from(value: [T; N]) -> Self { + todo!() + } +} + +pub struct DynamicPointerOffset { + value: u64, +} + +impl DynamicPointerOffset { + pub fn offset(&self) -> PointerOffset { + todo!() + } + + pub fn segment_id(&self) -> u8 { + todo!() + } + + pub fn has_segment_update(&self) -> u8 { + todo!() + } +} #[derive(Default)] pub enum AllocationStrategy { #[default] PowerOfTwo, - BestFit, Static, } -pub struct ResizableSharedMemoryBuilder {} +#[derive(Debug)] +pub struct ResizableSharedMemoryBuilder> +where + T::Builder: Debug, +{ + builder: T::Builder, + bucket_layout_hint: Layout, + number_of_buckets_hint: usize, +} -impl ResizableSharedMemoryBuilder { - /// Defines the prefix that the concept will use. - fn prefix(self, value: &FileName) -> Self { - todo!() +impl> ResizableSharedMemoryBuilder +where + T::Builder: Debug, +{ + pub fn new(name: &FileName) -> Self { + Self { + builder: T::Builder::new(name), + bucket_layout_hint: Layout::new::(), + number_of_buckets_hint: 1, + } } - /// Defines the suffix that the concept will use. - fn suffix(self, value: &FileName) -> Self { - todo!() + pub fn config(mut self, config: &T::Configuration) -> Self { + self.builder = self.builder.config(config); + self } /// Defines if a newly created [`SharedMemory`] owns the underlying resources - fn has_ownership(self, value: bool) -> Self { - todo!() + pub fn has_ownership(mut self, value: bool) -> Self { + self.builder = self.builder.has_ownership(value); + self } - fn bucket_layout_hint(self, layout: Layout) -> Self { - todo!() + pub fn bucket_layout_hint(mut self, layout: Layout) -> Self { + self.bucket_layout_hint = layout; + self } - fn number_of_buckets_hint(self, value: usize) -> Self { - todo!() + pub fn number_of_buckets_hint(mut self, value: usize) -> Self { + self.number_of_buckets_hint = value.max(1); + self } /// The timeout defines how long the [`SharedMemoryBuilder`] should wait for @@ -58,46 +136,96 @@ impl ResizableSharedMemoryBuilder { /// the initialization. This is required when the [`SharedMemory`] is created and initialized /// concurrently from another process. By default it is set to [`Duration::ZERO`] for no /// timeout. - fn timeout(self, value: Duration) -> Self { - todo!() + pub fn timeout(mut self, value: Duration) -> Self { + self.builder = self.builder.timeout(value); + self } /// Creates new [`SharedMemory`]. If it already exists the method will fail. - fn create>( - self, - ) -> Result, SharedMemoryCreateError> { - todo!() + pub fn create(self) -> Result, SharedMemoryCreateError> { + let initial_size = self.number_of_buckets_hint * self.bucket_layout_hint.size(); + let initial_allocator_config = iceoryx2_cal::shm_allocator::pool_allocator::Config { + bucket_layout: self.bucket_layout_hint, + }; + + let origin = format!("{:?}", self); + let shm = fail!(from origin, when self + .builder + .size(initial_size) + .create(&initial_allocator_config), + "Unable to create ResizableSharedMemory since the underlying shared memory could not be created."); + + Ok(ResizableSharedMemory { + shared_memory_vec: UniqueIndexVector::from([shm]), + current_idx: 0, + number_of_buckets: self.number_of_buckets_hint, + bucket_layout: self.bucket_layout_hint, + }) } /// Opens already existing [`SharedMemory`]. If it does not exist or the initialization is not /// yet finished the method will fail. - fn open>( - self, - ) -> Result, SharedMemoryOpenError> { + pub fn open(self) -> Result, SharedMemoryOpenError> { + let origin = format!("{:?}", self); + let shm = fail!(from origin, when self + .builder + .open(), + "Unable to open ResizableSharedMemoryView since the underlying shared memory could not be opened."); + + Ok(ResizableSharedMemoryView { + shared_memory_vec: UniqueIndexVector::from([shm]), + }) + } +} + +pub struct ResizableSharedMemoryView> { + shared_memory_vec: UniqueIndexVector, +} + +impl> ResizableSharedMemoryView { + fn translate_offset(&self, offset: DynamicPointerOffset) -> usize { + // updates and remaps shared memories + // todo!() } } pub struct ResizableSharedMemory> { - shared_memory_vec: VecDeque, + shared_memory_vec: UniqueIndexVector, + current_idx: u8, + number_of_buckets: usize, + bucket_layout: Layout, } impl> ResizableSharedMemory { - /// Returns the size of the shared memory. - fn size(&self) -> usize { + fn name(&self) -> &FileName { todo!() } - /// Returns the max supported alignment. - fn max_alignment(&self) -> usize; + unsafe fn remove( + name: &FileName, + config: &T::Configuration, + ) -> Result { + todo!() + } - /// Returns the start address of the shared memory. Used by the [`ShmPointer`] to calculate - /// the actual memory position. - fn payload_start_address(&self) -> usize; + fn does_exist( + name: &FileName, + config: &T::Configuration, + ) -> Result { + todo!() + } + + fn list CallbackProgression>( + config: &T::Configuration, + callback: F, + ) -> Result<(), NamedConceptListError> { + todo!() + } - /// Allocates memory. The alignment in the layout must be smaller or equal - /// [`SharedMemory::max_alignment()`] otherwise the method will fail. - fn allocate(&self, layout: std::alloc::Layout) -> Result; + fn allocate(&self, layout: std::alloc::Layout) -> Result { + todo!() + } /// Release previously allocated memory /// @@ -106,25 +234,30 @@ impl> ResizableSharedMemory { /// * the offset must be acquired with [`SharedMemory::allocate()`] - extracted from the /// [`ShmPointer`] /// * the layout must be identical to the one used in [`SharedMemory::allocate()`] - unsafe fn deallocate(&self, offset: PointerOffset, layout: std::alloc::Layout); + unsafe fn deallocate(&self, offset: PointerOffset, layout: std::alloc::Layout) { + todo!() + } /// Returns if the [`SharedMemory`] supports persistency, meaning that the underlying OS /// resource remain even when every [`SharedMemory`] instance in every process was removed. - fn does_support_persistency() -> bool; + fn does_support_persistency() -> bool { + todo!() + } /// Returns true if the [`SharedMemory`] holds the ownership, otherwise false - fn has_ownership(&self) -> bool; + fn has_ownership(&self) -> bool { + todo!() + } /// Acquires the ownership of the [`SharedMemory`]. When the object goes out of scope the /// underlying resources will be removed. - fn acquire_ownership(&self); + fn acquire_ownership(&self) { + todo!() + } /// Releases the ownership of the [`SharedMemory`] meaning when it goes out of scope the /// underlying resource will not be removed. - fn release_ownership(&self); - - /// The default suffix of every shared memory - fn default_suffix() -> FileName { - unsafe { FileName::new_unchecked(b".shm") } + fn release_ownership(&self) { + todo!() } }