From c7bb84f7a2122baa0d7e8ee1f5a0eef348aafed5 Mon Sep 17 00:00:00 2001 From: Noah <33094578+coolreader18@users.noreply.github.com> Date: Thu, 21 May 2020 21:06:27 -0500 Subject: [PATCH 1/2] Use StdRng instead of ThreadRng in _random --- vm/src/stdlib/random.rs | 89 ++++++++++++----------------------------- 1 file changed, 26 insertions(+), 63 deletions(-) diff --git a/vm/src/stdlib/random.rs b/vm/src/stdlib/random.rs index 09d784a2fd..2dae8ec715 100644 --- a/vm/src/stdlib/random.rs +++ b/vm/src/stdlib/random.rs @@ -9,21 +9,21 @@ mod _random { use crate::obj::objtype::PyClassRef; use crate::pyobject::{PyClassImpl, PyRef, PyResult, PyValue}; use crate::VirtualMachine; - use generational_arena::{self, Arena}; use num_bigint::{BigInt, Sign}; use num_traits::Signed; - use rand::RngCore; - use std::cell::RefCell; + use rand::{rngs::StdRng, RngCore, SeedableRng}; + + use std::sync::Mutex; #[derive(Debug)] enum PyRng { - Std(rand::rngs::ThreadRng), + Std(StdRng), MT(Box), } impl Default for PyRng { fn default() -> Self { - PyRng::Std(rand::thread_rng()) + PyRng::Std(StdRng::from_entropy()) } } @@ -54,47 +54,10 @@ mod _random { } } - thread_local!(static RNG_HANDLES: RefCell> = RefCell::new(Arena::new())); - - #[derive(Debug)] - struct RngHandle(generational_arena::Index); - impl RngHandle { - fn new(rng: PyRng) -> Self { - let idx = RNG_HANDLES.with(|arena| arena.borrow_mut().insert(rng)); - RngHandle(idx) - } - fn exec(&self, func: F) -> R - where - F: Fn(&mut PyRng) -> R, - { - RNG_HANDLES.with(|arena| { - func( - arena - .borrow_mut() - .get_mut(self.0) - .expect("index was removed"), - ) - }) - } - fn replace(&self, rng: PyRng) { - RNG_HANDLES.with(|arena| { - *arena - .borrow_mut() - .get_mut(self.0) - .expect("index was removed") = rng - }) - } - } - impl Drop for RngHandle { - fn drop(&mut self) { - RNG_HANDLES.with(|arena| arena.borrow_mut().remove(self.0)); - } - } - #[pyclass(name = "Random")] #[derive(Debug)] struct PyRandom { - rng: RngHandle, + rng: Mutex, } impl PyValue for PyRandom { @@ -108,14 +71,15 @@ mod _random { #[pyslot(new)] fn new(cls: PyClassRef, vm: &VirtualMachine) -> PyResult> { PyRandom { - rng: RngHandle::new(PyRng::default()), + rng: Mutex::default(), } .into_ref_with_type(vm, cls) } #[pymethod] fn random(&self) -> f64 { - self.rng.exec(mt19937::gen_res53) + let mut rng = self.rng.lock().unwrap(); + mt19937::gen_res53(&mut *rng) } #[pymethod] @@ -131,32 +95,31 @@ mod _random { } }; - self.rng.replace(new_rng); + *self.rng.lock().unwrap() = new_rng; } #[pymethod] fn getrandbits(&self, k: usize) -> BigInt { - self.rng.exec(|rng| { - let mut k = k; - let mut gen_u32 = |k| rng.next_u32() >> (32 - k) as u32; + let mut rng = self.rng.lock().unwrap(); + let mut k = k; + let mut gen_u32 = |k| rng.next_u32() >> (32 - k) as u32; - if k <= 32 { - return gen_u32(k).into(); - } + if k <= 32 { + return gen_u32(k).into(); + } - let words = (k - 1) / 8 + 1; - let mut wordarray = vec![0u32; words]; + let words = (k - 1) / 8 + 1; + let mut wordarray = vec![0u32; words]; - let it = wordarray.iter_mut(); - #[cfg(target_endian = "big")] - let it = it.rev(); - for word in it { - *word = gen_u32(k); - k -= 32; - } + let it = wordarray.iter_mut(); + #[cfg(target_endian = "big")] + let it = it.rev(); + for word in it { + *word = gen_u32(k); + k -= 32; + } - BigInt::from_slice(Sign::NoSign, &wordarray) - }) + BigInt::from_slice(Sign::NoSign, &wordarray) } } } From 63873e3343827ed52011c2ae8b298c6e54d0ac46 Mon Sep 17 00:00:00 2001 From: Noah <33094578+coolreader18@users.noreply.github.com> Date: Sat, 23 May 2020 12:09:01 -0500 Subject: [PATCH 2/2] Box StdRng --- vm/src/stdlib/random.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vm/src/stdlib/random.rs b/vm/src/stdlib/random.rs index 2dae8ec715..acb8f9869e 100644 --- a/vm/src/stdlib/random.rs +++ b/vm/src/stdlib/random.rs @@ -17,13 +17,13 @@ mod _random { #[derive(Debug)] enum PyRng { - Std(StdRng), + Std(Box), MT(Box), } impl Default for PyRng { fn default() -> Self { - PyRng::Std(StdRng::from_entropy()) + PyRng::Std(Box::new(StdRng::from_entropy())) } }