Skip to content

Commit

Permalink
Use const_in_array_repeat_expressions
Browse files Browse the repository at this point in the history
  • Loading branch information
taiki-e committed Jul 22, 2022
1 parent 0e14971 commit b553b4f
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 109 deletions.
16 changes: 9 additions & 7 deletions crossbeam-channel/src/flavors/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ struct Slot<T> {
}

impl<T> Slot<T> {
const UNINIT: Self = Self {
msg: UnsafeCell::new(MaybeUninit::uninit()),
state: AtomicUsize::new(0),
};

/// Waits until a message is written into the slot.
fn wait_write(&self) {
let backoff = Backoff::new();
Expand All @@ -72,13 +77,10 @@ struct Block<T> {
impl<T> Block<T> {
/// Creates an empty block.
fn new() -> Block<T> {
// SAFETY: This is safe because:
// [1] `Block::next` (AtomicPtr) may be safely zero initialized.
// [2] `Block::slots` (Array) may be safely zero initialized because of [3, 4].
// [3] `Slot::msg` (UnsafeCell) may be safely zero initialized because it
// holds a MaybeUninit.
// [4] `Slot::state` (AtomicUsize) may be safely zero initialized.
unsafe { MaybeUninit::zeroed().assume_init() }
Self {
next: AtomicPtr::new(ptr::null_mut()),
slots: [Slot::UNINIT; BLOCK_CAP],
}
}

/// Waits until the next pointer is set.
Expand Down
16 changes: 9 additions & 7 deletions crossbeam-deque/src/deque.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1119,6 +1119,11 @@ struct Slot<T> {
}

impl<T> Slot<T> {
const UNINIT: Self = Self {
task: UnsafeCell::new(MaybeUninit::uninit()),
state: AtomicUsize::new(0),
};

/// Waits until a task is written into the slot.
fn wait_write(&self) {
let backoff = Backoff::new();
Expand All @@ -1142,13 +1147,10 @@ struct Block<T> {
impl<T> Block<T> {
/// Creates an empty block that starts at `start_index`.
fn new() -> Block<T> {
// SAFETY: This is safe because:
// [1] `Block::next` (AtomicPtr) may be safely zero initialized.
// [2] `Block::slots` (Array) may be safely zero initialized because of [3, 4].
// [3] `Slot::task` (UnsafeCell) may be safely zero initialized because it
// holds a MaybeUninit.
// [4] `Slot::state` (AtomicUsize) may be safely zero initialized.
unsafe { MaybeUninit::zeroed().assume_init() }
Self {
next: AtomicPtr::new(ptr::null_mut()),
slots: [Slot::UNINIT; BLOCK_CAP],
}
}

/// Waits until the next pointer is set.
Expand Down
9 changes: 9 additions & 0 deletions crossbeam-epoch/src/deferred.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,15 @@ impl fmt::Debug for Deferred {
}

impl Deferred {
pub(crate) const NO_OP: Self = {
fn no_op_call(_raw: *mut u8) {}
Self {
call: no_op_call,
data: MaybeUninit::uninit(),
_marker: PhantomData,
}
};

/// Constructs a new `Deferred` from a `FnOnce()`.
pub(crate) fn new<F: FnOnce()>(f: F) -> Self {
let size = mem::size_of::<F>();
Expand Down
86 changes: 4 additions & 82 deletions crossbeam-epoch/src/internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,95 +106,19 @@ impl Bag {
}

impl Default for Bag {
#[rustfmt::skip]
fn default() -> Self {
// TODO: [no_op; MAX_OBJECTS] syntax blocked by https://github.com/rust-lang/rust/issues/49147
#[cfg(not(crossbeam_sanitize))]
return Bag {
Bag {
len: 0,
deferreds: [
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
],
};
#[cfg(crossbeam_sanitize)]
return Bag {
len: 0,
deferreds: [
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
Deferred::new(no_op_func),
],
};
deferreds: [Deferred::NO_OP; MAX_OBJECTS],
}
}
}

impl Drop for Bag {
fn drop(&mut self) {
// Call all deferred functions.
for deferred in &mut self.deferreds[..self.len] {
let no_op = Deferred::new(no_op_func);
let no_op = Deferred::NO_OP;
let owned_deferred = mem::replace(deferred, no_op);
owned_deferred.call();
}
Expand All @@ -210,8 +134,6 @@ impl fmt::Debug for Bag {
}
}

fn no_op_func() {}

/// A pair of an epoch and a bag.
#[derive(Default, Debug)]
struct SealedBag {
Expand Down
16 changes: 9 additions & 7 deletions crossbeam-queue/src/seg_queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ struct Slot<T> {
}

impl<T> Slot<T> {
const UNINIT: Self = Self {
value: UnsafeCell::new(MaybeUninit::uninit()),
state: AtomicUsize::new(0),
};

/// Waits until a value is written into the slot.
fn wait_write(&self) {
let backoff = Backoff::new();
Expand All @@ -58,13 +63,10 @@ struct Block<T> {
impl<T> Block<T> {
/// Creates an empty block that starts at `start_index`.
fn new() -> Block<T> {
// SAFETY: This is safe because:
// [1] `Block::next` (AtomicPtr) may be safely zero initialized.
// [2] `Block::slots` (Array) may be safely zero initialized because of [3, 4].
// [3] `Slot::value` (UnsafeCell) may be safely zero initialized because it
// holds a MaybeUninit.
// [4] `Slot::state` (AtomicUsize) may be safely zero initialized.
unsafe { MaybeUninit::zeroed().assume_init() }
Self {
next: AtomicPtr::new(ptr::null_mut()),
slots: [Slot::UNINIT; BLOCK_CAP],
}
}

/// Waits until the next pointer is set.
Expand Down
7 changes: 1 addition & 6 deletions crossbeam-utils/src/atomic/atomic_cell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -902,12 +902,7 @@ fn lock(addr: usize) -> &'static SeqLock {
const LEN: usize = 97;
#[allow(clippy::declare_interior_mutable_const)]
const L: SeqLock = SeqLock::new();
static LOCKS: [SeqLock; LEN] = [
L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L,
L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L,
L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L,
L, L, L, L, L, L, L,
];
static LOCKS: [SeqLock; LEN] = [L; LEN];

// If the modulus is a constant number, the compiler will use crazy math to transform this into
// a sequence of cheap arithmetic operations rather than using the slow modulo instruction.
Expand Down

0 comments on commit b553b4f

Please sign in to comment.