From 9fff898583b139970d0e1a0e4beaed42592835d2 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Fri, 8 Nov 2024 14:19:35 +0100 Subject: [PATCH] [#497] Integrate SlotMap --- Cargo.lock | 1 + iceoryx2-fal/Cargo.toml | 1 + iceoryx2-fal/src/resizable_shared_memory.rs | 133 ++++++++++---------- 3 files changed, 69 insertions(+), 66 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4faada26..5bb487bc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -754,6 +754,7 @@ dependencies = [ name = "iceoryx2-fal" version = "0.4.1" dependencies = [ + "iceoryx2-bb-container", "iceoryx2-bb-elementary", "iceoryx2-bb-log", "iceoryx2-bb-system-types", diff --git a/iceoryx2-fal/Cargo.toml b/iceoryx2-fal/Cargo.toml index 8f38a04d..65070a07 100644 --- a/iceoryx2-fal/Cargo.toml +++ b/iceoryx2-fal/Cargo.toml @@ -12,6 +12,7 @@ version = { workspace = true } [dependencies] iceoryx2-cal = { workspace = true } +iceoryx2-bb-container = { workspace = true } iceoryx2-bb-system-types = { workspace = true } iceoryx2-bb-elementary = { workspace = true } iceoryx2-bb-log = { workspace = true } diff --git a/iceoryx2-fal/src/resizable_shared_memory.rs b/iceoryx2-fal/src/resizable_shared_memory.rs index 567cb7dc..d9af645c 100644 --- a/iceoryx2-fal/src/resizable_shared_memory.rs +++ b/iceoryx2-fal/src/resizable_shared_memory.rs @@ -12,8 +12,11 @@ use std::alloc::Layout; use std::fmt::Debug; +use std::sync::atomic::Ordering; use std::time::Duration; +use iceoryx2_bb_container::semantic_string::SemanticString; +use iceoryx2_bb_container::slotmap::{SlotMap, SlotMapKey}; use iceoryx2_bb_elementary::CallbackProgression; use iceoryx2_bb_log::fail; use iceoryx2_bb_system_types::file_name::FileName; @@ -23,64 +26,30 @@ use iceoryx2_cal::shared_memory::{ }; use iceoryx2_cal::shm_allocator::pool_allocator::PoolAllocator; use iceoryx2_cal::shm_allocator::{PointerOffset, ShmAllocationError}; +use iceoryx2_pal_concurrency_sync::iox_atomic::IoxAtomicBool; -#[derive(Debug)] -pub struct UniqueIndexVector { - data: Vec, - idx_to_data: Vec, - current_idx: usize, +pub struct DynamicPointerOffset { + value: u64, } -impl UniqueIndexVector { - pub fn new() -> Self { +impl DynamicPointerOffset { + pub fn new(offset: usize, segment_id: u8) -> Self { Self { - data: vec![], - idx_to_data: vec![], - current_idx: 0, + value: (offset as u64) << 8 | segment_id as u64, } } - 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!() + PointerOffset::new((self.value >> 8) as usize) } pub fn segment_id(&self) -> u8 { - todo!() - } - - pub fn has_segment_update(&self) -> u8 { - todo!() + (self.value & 0x00000000000000ff) as u8 } } +const MAX_DATASEGMENTS: usize = 256; + #[derive(Default)] pub enum AllocationStrategy { #[default] @@ -93,6 +62,7 @@ pub struct ResizableSharedMemoryBuilder> where T::Builder: Debug, { + base_name: FileName, builder: T::Builder, bucket_layout_hint: Layout, number_of_buckets_hint: usize, @@ -103,8 +73,13 @@ where T::Builder: Debug, { pub fn new(name: &FileName) -> Self { + let mut first_shm_segment = *name; + first_shm_segment + .push_bytes(b"__0") + .expect("Adding __0 results in a valid file name"); Self { builder: T::Builder::new(name), + base_name: *name, bucket_layout_hint: Layout::new::(), number_of_buckets_hint: 1, } @@ -155,11 +130,18 @@ where .create(&initial_allocator_config), "Unable to create ResizableSharedMemory since the underlying shared memory could not be created."); + let mut shared_memory_map = SlotMap::new(MAX_DATASEGMENTS); + let current_idx = shared_memory_map + .insert(shm) + .expect("MAX_DATASEGMENTS is greater or equal 1"); + Ok(ResizableSharedMemory { - shared_memory_vec: UniqueIndexVector::from([shm]), - current_idx: 0, + base_name: self.base_name, + shared_memory_map, + current_idx, number_of_buckets: self.number_of_buckets_hint, bucket_layout: self.bucket_layout_hint, + has_ownership: IoxAtomicBool::new(true), }) } @@ -172,36 +154,55 @@ where .open(), "Unable to open ResizableSharedMemoryView since the underlying shared memory could not be opened."); + let mut shared_memory_map = SlotMap::new(MAX_DATASEGMENTS); + let current_idx = shared_memory_map + .insert(shm) + .expect("MAX_DATASEGMENTS is greater or equal 1"); + Ok(ResizableSharedMemoryView { - shared_memory_vec: UniqueIndexVector::from([shm]), + base_name: self.base_name, + shared_memory_map, + current_idx, }) } } pub struct ResizableSharedMemoryView> { - shared_memory_vec: UniqueIndexVector, + base_name: FileName, + shared_memory_map: SlotMap, + current_idx: SlotMapKey, } impl> ResizableSharedMemoryView { - fn translate_offset(&self, offset: DynamicPointerOffset) -> usize { - // updates and remaps shared memories - // - todo!() + fn update_map_view(&mut self) {} + + pub fn translate_offset(&mut self, offset: DynamicPointerOffset) -> usize { + let segment_id = offset.segment_id(); + let offset = offset.offset().value(); + + match self + .shared_memory_map + .get(SlotMapKey::new(segment_id as usize)) + { + None => { + self.update_map_view(); + todo!() + } + Some(shm) => offset + shm.payload_start_address(), + } } } pub struct ResizableSharedMemory> { - shared_memory_vec: UniqueIndexVector, - current_idx: u8, + base_name: FileName, + shared_memory_map: SlotMap, + current_idx: SlotMapKey, number_of_buckets: usize, bucket_layout: Layout, + has_ownership: IoxAtomicBool, } impl> ResizableSharedMemory { - fn name(&self) -> &FileName { - todo!() - } - unsafe fn remove( name: &FileName, config: &T::Configuration, @@ -240,24 +241,24 @@ impl> ResizableSharedMemory { /// 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 { - todo!() + pub fn does_support_persistency() -> bool { + T::does_support_persistency() } /// Returns true if the [`SharedMemory`] holds the ownership, otherwise false - fn has_ownership(&self) -> bool { - todo!() + pub fn has_ownership(&self) -> bool { + self.has_ownership.load(Ordering::Relaxed) } /// Acquires the ownership of the [`SharedMemory`]. When the object goes out of scope the /// underlying resources will be removed. - fn acquire_ownership(&self) { - todo!() + pub fn acquire_ownership(&self) { + self.has_ownership.store(true, Ordering::Relaxed); } /// Releases the ownership of the [`SharedMemory`] meaning when it goes out of scope the /// underlying resource will not be removed. - fn release_ownership(&self) { - todo!() + pub fn release_ownership(&self) { + self.has_ownership.store(false, Ordering::Relaxed); } }