Skip to content

Commit d024736

Browse files
committed
[#139] Improve bitset code
1 parent e29d53a commit d024736

File tree

3 files changed

+59
-43
lines changed

3 files changed

+59
-43
lines changed

iceoryx2-bb/lock-free/src/mpmc/bit_set.rs

+33-28
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,20 @@ pub mod details {
6666
pub type BitsetElement = AtomicU8;
6767
const BITSET_ELEMENT_BITSIZE: usize = core::mem::size_of::<BitsetElement>() * 8;
6868

69+
struct Id {
70+
index: usize,
71+
bit: u8,
72+
}
73+
74+
impl Id {
75+
fn new(value: usize) -> Id {
76+
Self {
77+
index: value / BITSET_ELEMENT_BITSIZE,
78+
bit: (value % BITSET_ELEMENT_BITSIZE) as u8,
79+
}
80+
}
81+
}
82+
6983
#[derive(Debug)]
7084
#[repr(C)]
7185
pub struct BitSet<PointerType: PointerTrait<BitsetElement>> {
@@ -191,20 +205,17 @@ pub mod details {
191205
);
192206
}
193207

194-
fn set_bit(&self, id: usize) -> bool {
195-
let index = id / BITSET_ELEMENT_BITSIZE;
196-
let bit = id % BITSET_ELEMENT_BITSIZE;
197-
198-
let data_ref = unsafe { &(*self.data_ptr.as_ptr().add(index)) };
208+
fn set_bit(&self, id: Id) -> bool {
209+
let data_ref = unsafe { &(*self.data_ptr.as_ptr().add(id.index)) };
199210
let mut current = data_ref.load(Ordering::Relaxed);
200-
let bit = 1 << bit;
211+
let mask = 1 << id.bit;
201212

202213
loop {
203-
if current & bit != 0 {
214+
if current & mask != 0 {
204215
return false;
205216
}
206217

207-
let current_with_bit = current | bit;
218+
let current_with_bit = current | mask;
208219

209220
match data_ref.compare_exchange(
210221
current,
@@ -221,24 +232,21 @@ pub mod details {
221232
}
222233
}
223234

224-
fn clear_bit(&self, id: usize) -> bool {
225-
let index = id / BITSET_ELEMENT_BITSIZE;
226-
let bit = id % BITSET_ELEMENT_BITSIZE;
227-
228-
let data_ref = unsafe { &(*self.data_ptr.as_ptr().add(index)) };
235+
fn clear_bit(&self, id: Id) -> bool {
236+
let data_ref = unsafe { &(*self.data_ptr.as_ptr().add(id.index)) };
229237
let mut current = data_ref.load(Ordering::Relaxed);
230-
let bit = 1 << bit;
238+
let mask = 1 << id.bit;
231239

232240
loop {
233-
if current & bit == 0 {
241+
if current & mask == 0 {
234242
return false;
235243
}
236244

237-
let current_with_bit = current & !bit;
245+
let current_with_cleared_bit = current & !mask;
238246

239247
match data_ref.compare_exchange(
240248
current,
241-
current_with_bit,
249+
current_with_cleared_bit,
242250
Ordering::Relaxed,
243251
Ordering::Relaxed,
244252
) {
@@ -262,7 +270,7 @@ pub mod details {
262270
id
263271
);
264272

265-
self.set_bit(id)
273+
self.set_bit(Id::new(id))
266274
}
267275

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

276-
let mut current_position = self.reset_position.load(Ordering::Relaxed);
277-
for _ in 0..self.capacity {
278-
current_position = (current_position + 1) % self.capacity;
279-
280-
if self.clear_bit(current_position) {
281-
self.reset_position
282-
.store(current_position, Ordering::Relaxed);
283-
return Some(current_position);
284+
let current_position = self.reset_position.load(Ordering::Relaxed);
285+
for pos in (current_position..self.capacity).chain(0..current_position) {
286+
if self.clear_bit(Id::new(pos)) {
287+
self.reset_position.store(pos + 1, Ordering::Relaxed);
288+
return Some(pos);
284289
}
285290
}
286291

@@ -295,15 +300,15 @@ pub mod details {
295300
for i in 0..self.array_capacity {
296301
let value = unsafe { (*self.data_ptr.as_ptr().add(i)).swap(0, Ordering::Relaxed) };
297302
let mut counter = 0;
303+
let main_index = i * BITSET_ELEMENT_BITSIZE;
298304
for b in 0..BITSET_ELEMENT_BITSIZE {
299-
let main_index = i * BITSET_ELEMENT_BITSIZE;
300305
if value & (1 << b) != 0 {
301306
callback(main_index + b);
302307
counter += 1;
303308
}
304309
}
305310

306-
if self.active_bits.fetch_sub(counter, Ordering::Relaxed) == 1 {
311+
if self.active_bits.fetch_sub(counter, Ordering::Relaxed) == counter {
307312
return;
308313
}
309314
}

iceoryx2-cal/src/event/common.rs

+25-11
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ pub mod details {
1515
use std::{fmt::Debug, marker::PhantomData, time::Duration};
1616

1717
use iceoryx2_bb_log::fail;
18+
use iceoryx2_bb_memory::bump_allocator::BumpAllocator;
1819
use iceoryx2_bb_system_types::{file_name::FileName, path::Path};
1920

2021
use crate::{
@@ -260,7 +261,8 @@ pub mod details {
260261
}
261262

262263
unsafe { self.storage.get().id_tracker.add(id)? };
263-
Ok(unsafe { self.storage.get().signal_mechanism.notify()? })
264+
unsafe { self.storage.get().signal_mechanism.notify()? };
265+
Ok(())
264266
}
265267
}
266268

@@ -447,6 +449,27 @@ pub mod details {
447449
}
448450
}
449451

452+
impl<
453+
Tracker: IdTracker,
454+
WaitMechanism: SignalMechanism,
455+
Storage: DynamicStorage<Management<Tracker, WaitMechanism>>,
456+
> ListenerBuilder<Tracker, WaitMechanism, Storage>
457+
{
458+
fn init(
459+
mgmt: &mut Management<Tracker, WaitMechanism>,
460+
allocator: &mut BumpAllocator,
461+
) -> bool {
462+
if unsafe { mgmt.id_tracker.init(allocator).is_err() } {
463+
return false;
464+
}
465+
if unsafe { mgmt.signal_mechanism.init().is_err() } {
466+
return false;
467+
}
468+
469+
true
470+
}
471+
}
472+
450473
impl<
451474
Tracker: IdTracker,
452475
WaitMechanism: SignalMechanism,
@@ -471,16 +494,7 @@ pub mod details {
471494
match Storage::Builder::new(&self.name)
472495
.config(&self.config.convert())
473496
.supplementary_size(Tracker::memory_size(id_tracker_capacity))
474-
.initializer(|mgmt, allocator| {
475-
if unsafe { mgmt.id_tracker.init(allocator).is_err() } {
476-
return false;
477-
}
478-
if unsafe { mgmt.signal_mechanism.init().is_err() } {
479-
return false;
480-
}
481-
482-
true
483-
})
497+
.initializer(Self::init)
484498
.has_ownership(true)
485499
.create(Management {
486500
id_tracker: unsafe { Tracker::new_uninit(id_tracker_capacity) },

iceoryx2-cal/src/event/id_tracker/bit_set.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,6 @@ impl IdTracker for RelocatableBitSet {
3737
}
3838

3939
unsafe fn acquire(&self) -> Option<TriggerId> {
40-
match self.reset_next() {
41-
Some(id) => Some(TriggerId::new(id as u64)),
42-
None => None,
43-
}
40+
self.reset_next().map(|id| TriggerId::new(id as u64))
4441
}
4542
}

0 commit comments

Comments
 (0)