mirror of
https://github.com/tokio-rs/tokio.git
synced 2026-09-07 00:00:08 +02:00
Replace XorShiftRng with a custom RNG (#466)
This commit is contained in:
committed by
Carl Lerche
parent
f1a7caea3f
commit
dc7202cfa9
@@ -21,13 +21,14 @@ use worker::{self, Worker, WorkerId};
|
|||||||
use futures::Poll;
|
use futures::Poll;
|
||||||
use futures::task::AtomicTask;
|
use futures::task::AtomicTask;
|
||||||
|
|
||||||
use std::cell::UnsafeCell;
|
use std::cell::Cell;
|
||||||
use std::sync::atomic::Ordering::{Acquire, AcqRel, Relaxed};
|
use std::num::Wrapping;
|
||||||
|
use std::sync::atomic::Ordering::{Acquire, AcqRel};
|
||||||
use std::sync::atomic::AtomicUsize;
|
use std::sync::atomic::AtomicUsize;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
|
|
||||||
use rand::{Rng, SeedableRng, XorShiftRng};
|
use rand;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) struct Pool {
|
pub(crate) struct Pool {
|
||||||
@@ -50,9 +51,6 @@ pub(crate) struct Pool {
|
|||||||
// shutdown process has completed.
|
// shutdown process has completed.
|
||||||
pub num_workers: AtomicUsize,
|
pub num_workers: AtomicUsize,
|
||||||
|
|
||||||
// Used to generate a thread local RNG seed
|
|
||||||
pub next_thread_id: AtomicUsize,
|
|
||||||
|
|
||||||
// Worker state
|
// Worker state
|
||||||
//
|
//
|
||||||
// A worker is a thread that is processing the work queue and polling
|
// A worker is a thread that is processing the work queue and polling
|
||||||
@@ -112,7 +110,6 @@ impl Pool {
|
|||||||
state: AtomicUsize::new(State::new().into()),
|
state: AtomicUsize::new(State::new().into()),
|
||||||
sleep_stack: worker::Stack::new(),
|
sleep_stack: worker::Stack::new(),
|
||||||
num_workers: AtomicUsize::new(0),
|
num_workers: AtomicUsize::new(0),
|
||||||
next_thread_id: AtomicUsize::new(0),
|
|
||||||
workers,
|
workers,
|
||||||
backup,
|
backup,
|
||||||
backup_stack,
|
backup_stack,
|
||||||
@@ -518,39 +515,25 @@ impl Pool {
|
|||||||
|
|
||||||
/// Generates a random number
|
/// Generates a random number
|
||||||
///
|
///
|
||||||
/// Uses a thread-local seeded XorShift.
|
/// Uses a thread-local random number generator based on XorShift.
|
||||||
pub fn rand_usize(&self) -> usize {
|
pub fn rand_usize(&self) -> usize {
|
||||||
// Use a thread-local random number generator. If the thread does not
|
thread_local! {
|
||||||
// have one yet, then seed a new one
|
static RNG: Cell<Wrapping<u32>> = {
|
||||||
thread_local!(static THREAD_RNG_KEY: UnsafeCell<Option<XorShiftRng>> = UnsafeCell::new(None));
|
// The initial seed must be non-zero.
|
||||||
|
let init = rand::random::<u32>() | 1;
|
||||||
THREAD_RNG_KEY.with(|t| {
|
Cell::new(Wrapping(init))
|
||||||
#[cfg(target_pointer_width = "32")]
|
|
||||||
fn new_rng(thread_id: usize) -> XorShiftRng {
|
|
||||||
XorShiftRng::from_seed([
|
|
||||||
thread_id as u32,
|
|
||||||
0x00000000,
|
|
||||||
0xa8a7d469,
|
|
||||||
0x97830e05])
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(target_pointer_width = "64")]
|
RNG.with(|rng| {
|
||||||
fn new_rng(thread_id: usize) -> XorShiftRng {
|
// This is the 32-bit variant of Xorshift.
|
||||||
XorShiftRng::from_seed([
|
// https://en.wikipedia.org/wiki/Xorshift
|
||||||
thread_id as u32,
|
let mut x = rng.get();
|
||||||
(thread_id >> 32) as u32,
|
x ^= x << 13;
|
||||||
0xa8a7d469,
|
x ^= x >> 17;
|
||||||
0x97830e05])
|
x ^= x << 5;
|
||||||
}
|
rng.set(x);
|
||||||
|
x.0 as usize
|
||||||
let thread_id = self.next_thread_id.fetch_add(1, Relaxed);
|
|
||||||
let rng = unsafe { &mut *t.get() };
|
|
||||||
|
|
||||||
if rng.is_none() {
|
|
||||||
*rng = Some(new_rng(thread_id));
|
|
||||||
}
|
|
||||||
|
|
||||||
rng.as_mut().unwrap().next_u32() as usize
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user