Skip to content

[#139] events with bitset #167

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

Merged
merged 27 commits into from
Apr 9, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
bbeac8a
[#139] Add and test bitset reset_next
elfenpiff Mar 19, 2024
f405333
[#139] Introduce signal and id_tracker traits
elfenpiff Mar 19, 2024
88886bf
[#139] Remove TriggerId trait and replace it with struct
elfenpiff Mar 19, 2024
998916b
[#139] Add bitset as id tracker
elfenpiff Mar 19, 2024
ed3da85
[#139] Provide id tracker impl
elfenpiff Mar 19, 2024
61876fb
[#139] Implement semaphore as signal mechanism
elfenpiff Mar 19, 2024
6bd832c
[#139] IdTracker is based on a RelocatableContainer
elfenpiff Mar 19, 2024
61669e0
[#139] Add tests for signal mechanism
elfenpiff Mar 20, 2024
bf7e68e
[#139] Finalize signal mechanism tests; rename wait into blocking_wait
elfenpiff Mar 25, 2024
4987d65
[#139] Add and test events based on new event concept
elfenpiff Mar 25, 2024
41ab76e
[#139] Add trigger id max test
elfenpiff Mar 25, 2024
e3698e0
[#139] Use new shm semaphore bitset event
elfenpiff Mar 25, 2024
4b70a15
[#139] Track active bits for performance
elfenpiff Mar 25, 2024
e6c5133
[#139] Add test to verify trigger id max settings
elfenpiff Mar 25, 2024
79ea3cb
[#139] Merge current main
elfenpiff Apr 4, 2024
e29d53a
[#139] Add documentation
elfenpiff Apr 4, 2024
66d1d78
[#139] Improve bitset code
elfenpiff Apr 5, 2024
668321d
[#139] Add bitset benchmark
elfenpiff Apr 8, 2024
93778cd
[#139] Adjust benchmark; add small optimization
elfenpiff Apr 8, 2024
998bfe9
[#139] Remove premature optimization trap active_bits to massively in…
elfenpiff Apr 8, 2024
b4f3687
[#139] Refactor benchmark so that it is a event service benchmark
elfenpiff Apr 8, 2024
9db4b1e
[#139] Add event benchmark to readme
elfenpiff Apr 8, 2024
99d056a
[#139] Fix doc examples
elfenpiff Apr 8, 2024
021142e
[#139] Reduce repetitions in event tests since uds have smaller buffe…
elfenpiff Apr 8, 2024
6f7ab35
[#139] Disable semaphore approach for mac os since atomic wait seems …
elfenpiff Apr 8, 2024
bd6a1de
[#139] Add detailed explanation and reworded doc
elfenpiff Apr 8, 2024
9ca036a
[#139] Do not use sem bitset in shm for windows
elfenpiff Apr 8, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 33 additions & 28 deletions iceoryx2-bb/lock-free/src/mpmc/bit_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,20 @@ pub mod details {
pub type BitsetElement = AtomicU8;
const BITSET_ELEMENT_BITSIZE: usize = core::mem::size_of::<BitsetElement>() * 8;

struct Id {
index: usize,
bit: u8,
}

impl Id {
fn new(value: usize) -> Id {
Self {
index: value / BITSET_ELEMENT_BITSIZE,
bit: (value % BITSET_ELEMENT_BITSIZE) as u8,
}
}
}

#[derive(Debug)]
#[repr(C)]
pub struct BitSet<PointerType: PointerTrait<BitsetElement>> {
Expand Down Expand Up @@ -191,20 +205,17 @@ pub mod details {
);
}

fn set_bit(&self, id: usize) -> bool {
let index = id / BITSET_ELEMENT_BITSIZE;
let bit = id % BITSET_ELEMENT_BITSIZE;

let data_ref = unsafe { &(*self.data_ptr.as_ptr().add(index)) };
fn set_bit(&self, id: Id) -> bool {
let data_ref = unsafe { &(*self.data_ptr.as_ptr().add(id.index)) };
let mut current = data_ref.load(Ordering::Relaxed);
let bit = 1 << bit;
let mask = 1 << id.bit;

loop {
if current & bit != 0 {
if current & mask != 0 {
return false;
}

let current_with_bit = current | bit;
let current_with_bit = current | mask;

match data_ref.compare_exchange(
current,
Expand All @@ -221,24 +232,21 @@ pub mod details {
}
}

fn clear_bit(&self, id: usize) -> bool {
let index = id / BITSET_ELEMENT_BITSIZE;
let bit = id % BITSET_ELEMENT_BITSIZE;

let data_ref = unsafe { &(*self.data_ptr.as_ptr().add(index)) };
fn clear_bit(&self, id: Id) -> bool {
let data_ref = unsafe { &(*self.data_ptr.as_ptr().add(id.index)) };
let mut current = data_ref.load(Ordering::Relaxed);
let bit = 1 << bit;
let mask = 1 << id.bit;

loop {
if current & bit == 0 {
if current & mask == 0 {
return false;
}

let current_with_bit = current & !bit;
let current_with_cleared_bit = current & !mask;

match data_ref.compare_exchange(
current,
current_with_bit,
current_with_cleared_bit,
Ordering::Relaxed,
Ordering::Relaxed,
) {
Expand All @@ -262,7 +270,7 @@ pub mod details {
id
);

self.set_bit(id)
self.set_bit(Id::new(id))
}

/// Resets the next set bit and returns the bit index. If no bit was set it returns
Expand All @@ -273,14 +281,11 @@ pub mod details {
return None;
}

let mut current_position = self.reset_position.load(Ordering::Relaxed);
for _ in 0..self.capacity {
current_position = (current_position + 1) % self.capacity;

if self.clear_bit(current_position) {
self.reset_position
.store(current_position, Ordering::Relaxed);
return Some(current_position);
let current_position = self.reset_position.load(Ordering::Relaxed);
for pos in (current_position..self.capacity).chain(0..current_position) {
if self.clear_bit(Id::new(pos)) {
self.reset_position.store(pos + 1, Ordering::Relaxed);
return Some(pos);
}
}

Expand All @@ -295,15 +300,15 @@ pub mod details {
for i in 0..self.array_capacity {
let value = unsafe { (*self.data_ptr.as_ptr().add(i)).swap(0, Ordering::Relaxed) };
let mut counter = 0;
let main_index = i * BITSET_ELEMENT_BITSIZE;
for b in 0..BITSET_ELEMENT_BITSIZE {
let main_index = i * BITSET_ELEMENT_BITSIZE;
if value & (1 << b) != 0 {
callback(main_index + b);
counter += 1;
}
}

if self.active_bits.fetch_sub(counter, Ordering::Relaxed) == 1 {
if self.active_bits.fetch_sub(counter, Ordering::Relaxed) == counter {
return;
}
}
Expand Down
36 changes: 25 additions & 11 deletions iceoryx2-cal/src/event/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pub mod details {
use std::{fmt::Debug, marker::PhantomData, time::Duration};

use iceoryx2_bb_log::fail;
use iceoryx2_bb_memory::bump_allocator::BumpAllocator;
use iceoryx2_bb_system_types::{file_name::FileName, path::Path};

use crate::{
Expand Down Expand Up @@ -260,7 +261,8 @@ pub mod details {
}

unsafe { self.storage.get().id_tracker.add(id)? };
Ok(unsafe { self.storage.get().signal_mechanism.notify()? })
unsafe { self.storage.get().signal_mechanism.notify()? };
Ok(())
}
}

Expand Down Expand Up @@ -447,6 +449,27 @@ pub mod details {
}
}

impl<
Tracker: IdTracker,
WaitMechanism: SignalMechanism,
Storage: DynamicStorage<Management<Tracker, WaitMechanism>>,
> ListenerBuilder<Tracker, WaitMechanism, Storage>
{
fn init(
mgmt: &mut Management<Tracker, WaitMechanism>,
allocator: &mut BumpAllocator,
) -> bool {
if unsafe { mgmt.id_tracker.init(allocator).is_err() } {
return false;
}
if unsafe { mgmt.signal_mechanism.init().is_err() } {
return false;
}

true
}
}

impl<
Tracker: IdTracker,
WaitMechanism: SignalMechanism,
Expand All @@ -471,16 +494,7 @@ pub mod details {
match Storage::Builder::new(&self.name)
.config(&self.config.convert())
.supplementary_size(Tracker::memory_size(id_tracker_capacity))
.initializer(|mgmt, allocator| {
if unsafe { mgmt.id_tracker.init(allocator).is_err() } {
return false;
}
if unsafe { mgmt.signal_mechanism.init().is_err() } {
return false;
}

true
})
.initializer(Self::init)
.has_ownership(true)
.create(Management {
id_tracker: unsafe { Tracker::new_uninit(id_tracker_capacity) },
Expand Down
5 changes: 1 addition & 4 deletions iceoryx2-cal/src/event/id_tracker/bit_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,6 @@ impl IdTracker for RelocatableBitSet {
}

unsafe fn acquire(&self) -> Option<TriggerId> {
match self.reset_next() {
Some(id) => Some(TriggerId::new(id as u64)),
None => None,
}
self.reset_next().map(|id| TriggerId::new(id as u64))
}
}
2 changes: 1 addition & 1 deletion iceoryx2-cal/src/event/id_tracker/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use iceoryx2_bb_elementary::relocatable_container::RelocatableContainer;

use super::{NotifierNotifyError, TriggerId};

/// The [`SignalMechanism`] is a building block for [`crate::event::Event`]
/// The [`IdTracker`] is a building block for [`crate::event::Event`]
/// concept. Its task is to track the origin of the signal that was sent
/// via the [`crate::event::signal_mechanism::SignalMechanism`].
pub trait IdTracker: RelocatableContainer + Send + Sync + Debug {
Expand Down
Loading