Skip to content

Commit 9e4c6bf

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

File tree

1 file changed

+33
-28
lines changed

1 file changed

+33
-28
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
}

0 commit comments

Comments
 (0)