Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#525] resizable shm support #527

Merged
22 changes: 11 additions & 11 deletions benchmarks/queue/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,36 +22,36 @@ const ITERATIONS: u64 = 10000000;

trait PushPop: Send + Sync {
fn push(&self, value: usize);
fn pop(&self) -> Option<usize>;
fn pop(&self) -> bool;
}

impl<const CAPACITY: usize> PushPop for Queue<usize, CAPACITY> {
fn push(&self, value: usize) {
unsafe { self.push(&value) };
}

fn pop(&self) -> Option<usize> {
unsafe { self.pop() }
fn pop(&self) -> bool {
unsafe { self.pop().is_some() }
}
}

impl<const CAPACITY: usize> PushPop for FixedSizeIndexQueue<CAPACITY> {
fn push(&self, value: usize) {
unsafe { self.push(value) };
unsafe { self.push(value as u64) };
}

fn pop(&self) -> Option<usize> {
unsafe { self.pop() }
fn pop(&self) -> bool {
unsafe { self.pop().is_some() }
}
}

impl<const CAPACITY: usize> PushPop for FixedSizeSafelyOverflowingIndexQueue<CAPACITY> {
fn push(&self, value: usize) {
unsafe { self.push(value) };
unsafe { self.push(value as u64) };
}

fn pop(&self) -> Option<usize> {
unsafe { self.pop() }
fn pop(&self) -> bool {
unsafe { self.pop().is_some() }
}
}

Expand All @@ -78,7 +78,7 @@ fn perform_benchmark<Q: PushPop>(

for _ in 0..args.iterations {
queue_a2b.push(0);
while queue_b2a.pop().is_none() {}
while !queue_b2a.pop() {}
}
});

Expand All @@ -90,7 +90,7 @@ fn perform_benchmark<Q: PushPop>(
start_benchmark_barrier.wait();

for _ in 0..args.iterations {
while queue_a2b.pop().is_none() {}
while !queue_a2b.pop() {}

queue_b2a.push(0);
}
Expand Down
17 changes: 7 additions & 10 deletions iceoryx2-bb/container/src/queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -333,8 +333,8 @@ pub mod details {
debug_assert!(
self.is_initialized
.load(std::sync::atomic::Ordering::Relaxed),
"From: {}, Undefined behavior - the object was not initialized with 'init' before.",
source
"From: MetaQueue<{}>::{}, Undefined behavior - the object was not initialized with 'init' before.",
std::any::type_name::<T>(), source
);
}

Expand Down Expand Up @@ -363,7 +363,7 @@ pub mod details {
}

pub(crate) unsafe fn peek_mut_impl(&mut self) -> Option<&mut T> {
self.verify_init(&format!("Queue<{}>::pop()", std::any::type_name::<T>()));
self.verify_init("peek_mut()");

if self.is_empty() {
return None;
Expand All @@ -375,7 +375,7 @@ pub mod details {
}

pub(crate) unsafe fn peek_impl(&self) -> Option<&T> {
self.verify_init(&format!("Queue<{}>::pop()", std::any::type_name::<T>()));
self.verify_init("peek()");

if self.is_empty() {
return None;
Expand All @@ -387,7 +387,7 @@ pub mod details {
}

pub(crate) unsafe fn pop_impl(&mut self) -> Option<T> {
self.verify_init(&format!("Queue<{}>::pop()", std::any::type_name::<T>()));
self.verify_init("pop()");

if self.is_empty() {
return None;
Expand All @@ -403,7 +403,7 @@ pub mod details {
}

pub(crate) unsafe fn push_impl(&mut self, value: T) -> bool {
self.verify_init(&format!("Queue<{}>::push()", std::any::type_name::<T>()));
self.verify_init("push()");

if self.len == self.capacity {
return false;
Expand All @@ -414,10 +414,7 @@ pub mod details {
}

pub(crate) unsafe fn push_with_overflow_impl(&mut self, value: T) -> Option<T> {
self.verify_init(&format!(
"Queue<{}>::push_with_overflow()",
std::any::type_name::<T>()
));
self.verify_init("push_with_overflow()");

let overridden_value = if self.len() == self.capacity() {
self.pop_impl()
Expand Down
26 changes: 26 additions & 0 deletions iceoryx2-bb/container/src/slotmap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ const INVALID: usize = usize::MAX;

#[doc(hidden)]
pub mod details {
use iceoryx2_pal_concurrency_sync::iox_atomic::IoxAtomicBool;

use super::*;

/// The iterator of a [`SlotMap`], [`RelocatableSlotMap`] or [`FixedSizeSlotMap`].
Expand Down Expand Up @@ -123,10 +125,21 @@ pub mod details {
data: MetaVec<Option<T>, Ptr>,
data_next_free_index: MetaQueue<usize, Ptr>,
idx_to_data_free_list_head: usize,
is_initialized: IoxAtomicBool,
len: usize,
}

impl<T, Ptr: GenericPointer> MetaSlotMap<T, Ptr> {
#[inline(always)]
fn verify_init(&self, source: &str) {
debug_assert!(
self.is_initialized
.load(std::sync::atomic::Ordering::Relaxed),
"From: MetaSlotMap<{}>::{}, Undefined behavior - the object was not initialized with 'init' before.",
std::any::type_name::<T>(), source
);
}

fn next_available_key_after(&self, start: SlotMapKey) -> Option<(SlotMapKey, &T)> {
let idx_to_data = &self.idx_to_data;

Expand Down Expand Up @@ -160,17 +173,20 @@ pub mod details {
}

pub(crate) unsafe fn iter_impl(&self) -> Iter<T, Ptr> {
self.verify_init("iter()");
Iter {
slotmap: self,
key: SlotMapKey(0),
}
}

pub(crate) unsafe fn contains_impl(&self, key: SlotMapKey) -> bool {
self.verify_init("contains()");
self.idx_to_data[key.0] != INVALID
}

pub(crate) unsafe fn get_impl(&self, key: SlotMapKey) -> Option<&T> {
self.verify_init("get()");
match self.idx_to_data[key.0] {
INVALID => None,
n => Some(self.data[n].as_ref().expect(
Expand All @@ -180,6 +196,7 @@ pub mod details {
}

pub(crate) unsafe fn get_mut_impl(&mut self, key: SlotMapKey) -> Option<&mut T> {
self.verify_init("get_mut()");
match self.idx_to_data[key.0] {
INVALID => None,
n => Some(self.data[n].as_mut().expect(
Expand Down Expand Up @@ -233,6 +250,7 @@ pub mod details {
}

pub(crate) unsafe fn insert_impl(&mut self, value: T) -> Option<SlotMapKey> {
self.verify_init("insert()");
self.acquire_next_free_index().map(|key| {
let key = SlotMapKey(key);
self.store_value(key, value);
Expand All @@ -241,11 +259,13 @@ pub mod details {
}

pub(crate) unsafe fn insert_at_impl(&mut self, key: SlotMapKey, value: T) -> bool {
self.verify_init("insert_at()");
self.claim_index(key.value());
self.store_value(key, value)
}

pub(crate) unsafe fn store_value(&mut self, key: SlotMapKey, value: T) -> bool {
self.verify_init("store()");
if key.0 > self.capacity_impl() {
return false;
}
Expand All @@ -264,6 +284,7 @@ pub mod details {
}

pub(crate) unsafe fn remove_impl(&mut self, key: SlotMapKey) -> bool {
self.verify_init("remove()");
if key.0 > self.idx_to_data.len() {
return false;
}
Expand All @@ -283,6 +304,7 @@ pub mod details {
}

pub(crate) unsafe fn next_free_key_impl(&self) -> Option<SlotMapKey> {
self.verify_init("next_free_key()");
if self.idx_to_data_free_list_head == INVALID {
return None;
}
Expand Down Expand Up @@ -316,6 +338,7 @@ pub mod details {
idx_to_data_free_list: RelocatableVec::new_uninit(capacity),
data: RelocatableVec::new_uninit(capacity),
data_next_free_index: RelocatableQueue::new_uninit(capacity),
is_initialized: IoxAtomicBool::new(false),
}
}

Expand All @@ -338,6 +361,8 @@ pub mod details {
"{msg} since the underlying data_next_free_index queue could not be initialized.");

self.initialize_data_structures();
self.is_initialized
.store(true, std::sync::atomic::Ordering::Relaxed);
Ok(())
}

Expand All @@ -356,6 +381,7 @@ pub mod details {
idx_to_data_free_list: MetaVec::new(capacity),
data: MetaVec::new(capacity),
data_next_free_index: MetaQueue::new(capacity),
is_initialized: IoxAtomicBool::new(true),
};
unsafe { new_self.initialize_data_structures() };
new_self
Expand Down
12 changes: 6 additions & 6 deletions iceoryx2-bb/container/src/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,14 +181,14 @@ pub mod details {
type Target = [T];

fn deref(&self) -> &Self::Target {
self.verify_init(&format!("Vec<{}>::push()", std::any::type_name::<T>()));
self.verify_init("deref()");
unsafe { core::slice::from_raw_parts((*self.data_ptr.as_ptr()).as_ptr(), self.len) }
}
}

impl<T, Ptr: GenericPointer> DerefMut for MetaVec<T, Ptr> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.verify_init(&format!("Vec<{}>::push()", std::any::type_name::<T>()));
self.verify_init("deref_mut()");
unsafe {
core::slice::from_raw_parts_mut(
(*self.data_ptr.as_mut_ptr()).as_mut_ptr(),
Expand Down Expand Up @@ -222,8 +222,8 @@ pub mod details {
debug_assert!(
self.is_initialized
.load(std::sync::atomic::Ordering::Relaxed),
"From: {}, Undefined behavior - the object was not initialized with 'init' before.",
source
"From: MetaVec<{}>::{}, Undefined behavior - the object was not initialized with 'init' before.",
core::any::type_name::<T>(), source
);
}

Expand Down Expand Up @@ -252,7 +252,7 @@ pub mod details {
return false;
}

self.verify_init(&format!("Vec<{}>::push()", std::any::type_name::<T>()));
self.verify_init("push()");
self.push_unchecked(value);
true
}
Expand Down Expand Up @@ -303,7 +303,7 @@ pub mod details {
return None;
}

self.verify_init(&format!("Vec<{}>::pop()", std::any::type_name::<T>()));
self.verify_init("pop()");
Some(self.pop_unchecked())
}

Expand Down
8 changes: 4 additions & 4 deletions iceoryx2-bb/lock-free/src/mpmc/bit_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ pub mod details {
fn verify_init(&self, source: &str) {
debug_assert!(
self.is_memory_initialized.load(Ordering::Relaxed),
"Undefined behavior when calling \"{}\" and the object is not initialized.",
"Undefined behavior when calling BitSet::{} and the object is not initialized.",
source
);
}
Expand Down Expand Up @@ -242,7 +242,7 @@ pub mod details {
/// If the bit was successfully set it returns true, if the bit was already set it
/// returns false.
pub fn set(&self, id: usize) -> bool {
self.verify_init("set");
self.verify_init("set()");
debug_assert!(
id < self.capacity,
"This should never happen. Out of bounds access with index {}.",
Expand All @@ -255,7 +255,7 @@ pub mod details {
/// Resets the next set bit and returns the bit index. If no bit was set it returns
/// [`None`].
pub fn reset_next(&self) -> Option<usize> {
self.verify_init("reset_next");
self.verify_init("reset_next()");

let current_position = self.reset_position.load(Ordering::Relaxed);
for pos in (current_position..self.capacity).chain(0..current_position) {
Expand All @@ -271,7 +271,7 @@ pub mod details {
/// Reset every set bit in the BitSet and call the provided callback for every bit that
/// was set. This is the most efficient way to acquire all bits that were set.
pub fn reset_all<F: FnMut(usize)>(&self, mut callback: F) {
self.verify_init("reset_all");
self.verify_init("reset_all()");

for i in 0..self.array_capacity {
let value = unsafe { (*self.data_ptr.as_ptr().add(i)).swap(0, Ordering::Relaxed) };
Expand Down
Loading
Loading