Skip to content

Commit

Permalink
threadpool: use std RandomState for XorShift seeding
Browse files Browse the repository at this point in the history
This allows dropping _rand_ crate dep here, accept as a dev dependency
for tests or benchmarks.
  • Loading branch information
dekellum committed Jul 17, 2019
1 parent d0bb161 commit 1b0e41a
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 7 deletions.
2 changes: 1 addition & 1 deletion tokio-threadpool/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ crossbeam-deque = "0.7.0"
crossbeam-queue = "0.1.0"
crossbeam-utils = "0.6.4"
num_cpus = "1.2"
rand = "0.7"
slab = "0.4.1"
log = "0.4"

[dev-dependencies]
rand = "0.7"
env_logger = "0.5"
async-util = { git = "https://github.com/tokio-rs/async" }
tokio = { version = "0.2.0", path = "../tokio" }
Expand Down
25 changes: 19 additions & 6 deletions tokio-threadpool/src/pool/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ use crossbeam_deque::Injector;
use crossbeam_utils::CachePadded;

use log::{debug, error, trace};
use rand;
use std::cell::Cell;
use std::collections::hash_map::RandomState;
use std::hash::{BuildHasher, Hash, Hasher};
use std::num::Wrapping;
use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering::{AcqRel, Acquire};
Expand Down Expand Up @@ -422,11 +423,7 @@ impl Pool {
/// Uses a thread-local random number generator based on XorShift.
pub fn rand_usize(&self) -> usize {
thread_local! {
static RNG: Cell<Wrapping<u32>> = {
// The initial seed must be non-zero.
let init = rand::random::<u32>() | 1;
Cell::new(Wrapping(init))
}
static RNG: Cell<Wrapping<u32>> = Cell::new(Wrapping(prng_seed()));
}

RNG.with(|rng| {
Expand All @@ -450,3 +447,19 @@ impl PartialEq for Pool {

unsafe impl Send for Pool {}
unsafe impl Sync for Pool {}

// Piggyback on libstd's mechanism for obtaining system randomness for default
// hasher, and hash on current thread id for a seed value.
fn prng_seed() -> u32 {
let mut hasher = RandomState::new().build_hasher();
thread::current().id().hash(&mut hasher);
let hash: u64 = hasher.finish();
let seed = (hash as u32) ^ ((hash >> 32) as u32);

// ensure non-zero
if seed == 0 {
0x9b4e_6d25 // misc bits
} else {
seed
}
}

0 comments on commit 1b0e41a

Please sign in to comment.