fix concurrent writer/uninitialized memory bug with AtomicBucket
This commit is contained in:
parent
507493a59a
commit
8b57975110
|
@ -5,14 +5,19 @@ use std::{
|
||||||
sync::atomic::{AtomicUsize, Ordering},
|
sync::atomic::{AtomicUsize, Ordering},
|
||||||
};
|
};
|
||||||
|
|
||||||
const BLOCK_SIZE: usize = 512;
|
#[cfg(target_pointer_width = "16")]
|
||||||
|
const BLOCK_SIZE: usize = 16;
|
||||||
|
#[cfg(target_pointer_width = "32")]
|
||||||
|
const BLOCK_SIZE: usize = 32;
|
||||||
|
#[cfg(target_pointer_width = "64")]
|
||||||
|
const BLOCK_SIZE: usize = 64;
|
||||||
|
|
||||||
/// Discrete chunk of values with atomic read/write access.
|
/// Discrete chunk of values with atomic read/write access.
|
||||||
struct Block<T> {
|
struct Block<T> {
|
||||||
// Write index.
|
// Write index.
|
||||||
write: AtomicUsize,
|
write: AtomicUsize,
|
||||||
|
|
||||||
// Read index.
|
// Read bitmap.
|
||||||
read: AtomicUsize,
|
read: AtomicUsize,
|
||||||
|
|
||||||
// The individual slots.
|
// The individual slots.
|
||||||
|
@ -35,7 +40,7 @@ impl<T> Block<T> {
|
||||||
|
|
||||||
/// Gets the current length of this block.
|
/// Gets the current length of this block.
|
||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
self.read.load(Ordering::Acquire)
|
self.read.load(Ordering::Acquire).trailing_ones() as usize
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets a slice of the data written to this block.
|
/// Gets a slice of the data written to this block.
|
||||||
|
@ -71,7 +76,7 @@ impl<T> Block<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scoot our read index forward.
|
// Scoot our read index forward.
|
||||||
self.read.fetch_add(1, Ordering::AcqRel);
|
self.read.fetch_or(1 << index, Ordering::AcqRel);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -324,6 +329,7 @@ mod tests {
|
||||||
|
|
||||||
let result = block.push(42);
|
let result = block.push(42);
|
||||||
assert!(result.is_ok());
|
assert!(result.is_ok());
|
||||||
|
assert_eq!(block.len(), 1);
|
||||||
|
|
||||||
let data = block.data();
|
let data = block.data();
|
||||||
assert_eq!(data.len(), 1);
|
assert_eq!(data.len(), 1);
|
||||||
|
|
Loading…
Reference in New Issue