From 1b0e41a127438620e15d391bb249072cd56c67d1 Mon Sep 17 00:00:00 2001 From: David Kellum Date: Wed, 17 Jul 2019 09:56:23 -0700 Subject: [PATCH] threadpool: use std RandomState for XorShift seeding This allows dropping _rand_ crate dep here, accept as a dev dependency for tests or benchmarks. --- tokio-threadpool/Cargo.toml | 2 +- tokio-threadpool/src/pool/mod.rs | 25 +++++++++++++++++++------ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/tokio-threadpool/Cargo.toml b/tokio-threadpool/Cargo.toml index e4f90c7a50f..4f05b6087bb 100644 --- a/tokio-threadpool/Cargo.toml +++ b/tokio-threadpool/Cargo.toml @@ -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" } diff --git a/tokio-threadpool/src/pool/mod.rs b/tokio-threadpool/src/pool/mod.rs index 0b14fcf124e..6e9d4c38548 100644 --- a/tokio-threadpool/src/pool/mod.rs +++ b/tokio-threadpool/src/pool/mod.rs @@ -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}; @@ -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> = { - // The initial seed must be non-zero. - let init = rand::random::() | 1; - Cell::new(Wrapping(init)) - } + static RNG: Cell> = Cell::new(Wrapping(prng_seed())); } RNG.with(|rng| { @@ -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 + } +}