Skip to content

Commit

Permalink
Merge pull request #414 from Shnatsel/remove-arrayvec-dependency
Browse files Browse the repository at this point in the history
Remove ArrayVec dependency
  • Loading branch information
Vtec234 committed Sep 17, 2019
2 parents c725403 + 1349724 commit ae148de
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 13 deletions.
6 changes: 1 addition & 5 deletions crossbeam-epoch/Cargo.toml
Expand Up @@ -17,7 +17,7 @@ categories = ["concurrency", "memory-management", "no-std"]

[features]
default = ["std"]
nightly = ["crossbeam-utils/nightly", "arrayvec/use_union"]
nightly = ["crossbeam-utils/nightly"]
std = ["crossbeam-utils/std", "lazy_static"]
alloc = ["crossbeam-utils/alloc"]
sanitize = [] # Makes it more likely to trigger any potential data races.
Expand All @@ -26,10 +26,6 @@ sanitize = [] # Makes it more likely to trigger any potential data races.
cfg-if = "0.1.2"
memoffset = "0.5"

[dependencies.arrayvec]
version = "0.4"
default-features = false

[dependencies.crossbeam-utils]
version = "0.6"
path = "../crossbeam-utils"
Expand Down
57 changes: 50 additions & 7 deletions crossbeam-epoch/src/internal.rs
Expand Up @@ -38,11 +38,10 @@
use core::cell::{Cell, UnsafeCell};
use core::mem::{self, ManuallyDrop};
use core::num::Wrapping;
use core::ptr;
use core::{ptr, fmt};
use core::sync::atomic;
use core::sync::atomic::Ordering;

use arrayvec::ArrayVec;
use crossbeam_utils::CachePadded;

use atomic::{Shared, Owned};
Expand All @@ -60,10 +59,10 @@ const MAX_OBJECTS: usize = 64;
const MAX_OBJECTS: usize = 4;

/// A bag of deferred functions.
#[derive(Default, Debug)]
pub struct Bag {
/// Stashed objects.
deferreds: ArrayVec<[Deferred; MAX_OBJECTS]>,
deferreds: [Deferred; MAX_OBJECTS],
len: usize
}

/// `Bag::try_push()` requires that it is safe for another thread to execute the given functions.
Expand All @@ -77,7 +76,7 @@ impl Bag {

/// Returns `true` if the bag is empty.
pub fn is_empty(&self) -> bool {
self.deferreds.is_empty()
self.len == 0
}

/// Attempts to insert a deferred function into the bag.
Expand All @@ -89,7 +88,13 @@ impl Bag {
///
/// It should be safe for another thread to execute the given function.
pub unsafe fn try_push(&mut self, deferred: Deferred) -> Result<(), Deferred> {
self.deferreds.try_push(deferred).map_err(|e| e.element())
if self.len < MAX_OBJECTS {
self.deferreds[self.len] = deferred;
self.len += 1;
Ok(())
} else {
Err(deferred)
}
}

/// Seals the bag with the given epoch.
Expand All @@ -98,15 +103,53 @@ impl Bag {
}
}

impl Default for Bag {
fn default() -> Self {
// TODO: [no_op; MAX_OBJECTS] syntax blocked by https://github.com/rust-lang/rust/issues/49147
#[cfg(not(feature = "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),
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(feature = "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)] };
}
}

impl Drop for Bag {
fn drop(&mut self) {
// Call all deferred functions.
for deferred in self.deferreds.drain(..) {
for i in 0..self.len {
let no_op = Deferred::new(no_op_func);
let deferred = mem::replace(&mut self.deferreds[i], no_op);
deferred.call();
}
}
}

// can't #[derive(Debug)] because Debug is not implemented for arrays 64 items long
impl fmt::Debug for Bag {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("Bag").field("deferreds", &&self.deferreds[..self.len]).finish()
}
}

fn no_op_func() {}

/// A pair of an epoch and a bag.
#[derive(Default, Debug)]
struct SealedBag {
Expand Down
1 change: 0 additions & 1 deletion crossbeam-epoch/src/lib.rs
Expand Up @@ -79,7 +79,6 @@ cfg_if! {
)]
cfg_if! {
if #[cfg(any(feature = "alloc", feature = "std"))] {
extern crate arrayvec;
extern crate crossbeam_utils;
#[macro_use]
extern crate memoffset;
Expand Down

0 comments on commit ae148de

Please sign in to comment.