@@ -9,21 +9,21 @@ mod _random {
9
9
use crate :: obj:: objtype:: PyClassRef ;
10
10
use crate :: pyobject:: { PyClassImpl , PyRef , PyResult , PyValue } ;
11
11
use crate :: VirtualMachine ;
12
- use generational_arena:: { self , Arena } ;
13
12
use num_bigint:: { BigInt , Sign } ;
14
13
use num_traits:: Signed ;
15
- use rand:: RngCore ;
16
- use std:: cell:: RefCell ;
14
+ use rand:: { rngs:: StdRng , RngCore , SeedableRng } ;
15
+
16
+ use std:: sync:: Mutex ;
17
17
18
18
#[ derive( Debug ) ]
19
19
enum PyRng {
20
- Std ( rand :: rngs :: ThreadRng ) ,
20
+ Std ( Box < StdRng > ) ,
21
21
MT ( Box < mt19937:: MT19937 > ) ,
22
22
}
23
23
24
24
impl Default for PyRng {
25
25
fn default ( ) -> Self {
26
- PyRng :: Std ( rand :: thread_rng ( ) )
26
+ PyRng :: Std ( Box :: new ( StdRng :: from_entropy ( ) ) )
27
27
}
28
28
}
29
29
@@ -54,47 +54,10 @@ mod _random {
54
54
}
55
55
}
56
56
57
- thread_local ! ( static RNG_HANDLES : RefCell <Arena <PyRng >> = RefCell :: new( Arena :: new( ) ) ) ;
58
-
59
- #[ derive( Debug ) ]
60
- struct RngHandle ( generational_arena:: Index ) ;
61
- impl RngHandle {
62
- fn new ( rng : PyRng ) -> Self {
63
- let idx = RNG_HANDLES . with ( |arena| arena. borrow_mut ( ) . insert ( rng) ) ;
64
- RngHandle ( idx)
65
- }
66
- fn exec < F , R > ( & self , func : F ) -> R
67
- where
68
- F : Fn ( & mut PyRng ) -> R ,
69
- {
70
- RNG_HANDLES . with ( |arena| {
71
- func (
72
- arena
73
- . borrow_mut ( )
74
- . get_mut ( self . 0 )
75
- . expect ( "index was removed" ) ,
76
- )
77
- } )
78
- }
79
- fn replace ( & self , rng : PyRng ) {
80
- RNG_HANDLES . with ( |arena| {
81
- * arena
82
- . borrow_mut ( )
83
- . get_mut ( self . 0 )
84
- . expect ( "index was removed" ) = rng
85
- } )
86
- }
87
- }
88
- impl Drop for RngHandle {
89
- fn drop ( & mut self ) {
90
- RNG_HANDLES . with ( |arena| arena. borrow_mut ( ) . remove ( self . 0 ) ) ;
91
- }
92
- }
93
-
94
57
#[ pyclass( name = "Random" ) ]
95
58
#[ derive( Debug ) ]
96
59
struct PyRandom {
97
- rng : RngHandle ,
60
+ rng : Mutex < PyRng > ,
98
61
}
99
62
100
63
impl PyValue for PyRandom {
@@ -108,14 +71,15 @@ mod _random {
108
71
#[ pyslot( new) ]
109
72
fn new ( cls : PyClassRef , vm : & VirtualMachine ) -> PyResult < PyRef < Self > > {
110
73
PyRandom {
111
- rng : RngHandle :: new ( PyRng :: default ( ) ) ,
74
+ rng : Mutex :: default ( ) ,
112
75
}
113
76
. into_ref_with_type ( vm, cls)
114
77
}
115
78
116
79
#[ pymethod]
117
80
fn random ( & self ) -> f64 {
118
- self . rng . exec ( mt19937:: gen_res53)
81
+ let mut rng = self . rng . lock ( ) . unwrap ( ) ;
82
+ mt19937:: gen_res53 ( & mut * rng)
119
83
}
120
84
121
85
#[ pymethod]
@@ -131,32 +95,31 @@ mod _random {
131
95
}
132
96
} ;
133
97
134
- self . rng . replace ( new_rng ) ;
98
+ * self . rng . lock ( ) . unwrap ( ) = new_rng ;
135
99
}
136
100
137
101
#[ pymethod]
138
102
fn getrandbits ( & self , k : usize ) -> BigInt {
139
- self . rng . exec ( |rng| {
140
- let mut k = k;
141
- let mut gen_u32 = |k| rng. next_u32 ( ) >> ( 32 - k) as u32 ;
103
+ let mut rng = self . rng . lock ( ) . unwrap ( ) ;
104
+ let mut k = k;
105
+ let mut gen_u32 = |k| rng. next_u32 ( ) >> ( 32 - k) as u32 ;
142
106
143
- if k <= 32 {
144
- return gen_u32 ( k) . into ( ) ;
145
- }
107
+ if k <= 32 {
108
+ return gen_u32 ( k) . into ( ) ;
109
+ }
146
110
147
- let words = ( k - 1 ) / 8 + 1 ;
148
- let mut wordarray = vec ! [ 0u32 ; words] ;
111
+ let words = ( k - 1 ) / 8 + 1 ;
112
+ let mut wordarray = vec ! [ 0u32 ; words] ;
149
113
150
- let it = wordarray. iter_mut ( ) ;
151
- #[ cfg( target_endian = "big" ) ]
152
- let it = it. rev ( ) ;
153
- for word in it {
154
- * word = gen_u32 ( k) ;
155
- k -= 32 ;
156
- }
114
+ let it = wordarray. iter_mut ( ) ;
115
+ #[ cfg( target_endian = "big" ) ]
116
+ let it = it. rev ( ) ;
117
+ for word in it {
118
+ * word = gen_u32 ( k) ;
119
+ k -= 32 ;
120
+ }
157
121
158
- BigInt :: from_slice ( Sign :: NoSign , & wordarray)
159
- } )
122
+ BigInt :: from_slice ( Sign :: NoSign , & wordarray)
160
123
}
161
124
}
162
125
}
0 commit comments