Created
November 13, 2015 11:59
-
-
Save abonander/6ea304b19781b670a26e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![cfg_attr(test, feature(test))] | |
#[cfg(test)] | |
#[macro_use] | |
extern crate lazy_static; | |
use std::mem; | |
use std::sync::atomic::{ATOMIC_USIZE_INIT, AtomicUsize, Ordering}; | |
pub const INIT: AtomicBitSet = AtomicBitSet { | |
bits: ATOMIC_USIZE_INIT, | |
_padding: [0; 7], | |
}; | |
pub struct AtomicBitSet { | |
bits: AtomicUsize, | |
_padding: [usize; 7], | |
} | |
impl AtomicBitSet { | |
pub fn new() -> AtomicBitSet { | |
Self::from_bits(0) | |
} | |
pub fn from_bits(bits: usize) -> AtomicBitSet { | |
AtomicBitSet { | |
bits: AtomicUsize::new(bits), | |
_padding: [0; 7], | |
} | |
} | |
pub fn set(&self, idx: usize, val: bool, ord: Ordering) -> bool { | |
let shift_val = 1 << idx; | |
(if val { | |
self.bits.fetch_or(shift_val, ord) | |
} else { | |
self.bits.fetch_and(!shift_val, ord) | |
} & shift_val) != 0 | |
} | |
pub fn get(&self, idx: usize, ord: Ordering) -> bool { | |
self.bits.load(ord) & (1 << idx) != 0 | |
} | |
pub fn clear_all(&self, ord: Ordering) -> AtomicBitSet { | |
Self::from_bits(self.bits.swap(0, ord)) | |
} | |
} | |
#[inline(always)] | |
fn assert_idx(idx: usize) { | |
assert!(idx < mem::size_of::<usize>() * 8); | |
} | |
#[cfg(test)] | |
mod test { | |
extern crate test; | |
use self::test::Bencher; | |
use super::*; | |
use std::mem; | |
use std::sync::atomic::{ATOMIC_BOOL_INIT, AtomicBool, Ordering}; | |
static SHARED_BITSET: AtomicBitSet = INIT; | |
lazy_static! { | |
static ref SHARED_BOOLS: [AtomicBool; 64] = unsafe { mem::transmute([0usize; 64]) }; | |
} | |
#[bench] | |
fn bench_atomic_bit_set(bench: &mut Bencher) { | |
bench.iter(|| for i in 0 .. 64 { | |
let val = SHARED_BITSET.get(i, Ordering::Relaxed); | |
SHARED_BITSET.set(i, !val, Ordering::Relaxed); | |
}); | |
} | |
#[bench] | |
fn bench_atomic_bool_array(bench: &mut Bencher) { | |
bench.iter(|| for i in 0 .. 64 { | |
let val = SHARED_BOOLS[i].load(Ordering::Relaxed); | |
SHARED_BOOLS[i].store(!val, Ordering::Relaxed); | |
}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment