@@ -30,6 +30,8 @@ pub use vec::AppendOnlyVec;
30
30
31
31
mod vec;
32
32
33
+ static PARALLEL : std:: sync:: atomic:: AtomicBool = std:: sync:: atomic:: AtomicBool :: new ( false ) ;
34
+
33
35
cfg_if ! {
34
36
if #[ cfg( not( parallel_compiler) ) ] {
35
37
pub auto trait Send { }
@@ -182,33 +184,6 @@ cfg_if! {
182
184
183
185
use std:: cell:: Cell ;
184
186
185
- #[ derive( Debug ) ]
186
- pub struct WorkerLocal <T >( OneThread <T >) ;
187
-
188
- impl <T > WorkerLocal <T > {
189
- /// Creates a new worker local where the `initial` closure computes the
190
- /// value this worker local should take for each thread in the thread pool.
191
- #[ inline]
192
- pub fn new<F : FnMut ( usize ) -> T >( mut f: F ) -> WorkerLocal <T > {
193
- WorkerLocal ( OneThread :: new( f( 0 ) ) )
194
- }
195
-
196
- /// Returns the worker-local value for each thread
197
- #[ inline]
198
- pub fn into_inner( self ) -> Vec <T > {
199
- vec![ OneThread :: into_inner( self . 0 ) ]
200
- }
201
- }
202
-
203
- impl <T > Deref for WorkerLocal <T > {
204
- type Target = T ;
205
-
206
- #[ inline( always) ]
207
- fn deref( & self ) -> & T {
208
- & self . 0
209
- }
210
- }
211
-
212
187
pub type MTRef <' a, T > = & ' a mut T ;
213
188
214
189
#[ derive( Debug , Default ) ]
@@ -328,8 +303,6 @@ cfg_if! {
328
303
} ;
329
304
}
330
305
331
- pub use rayon_core:: WorkerLocal ;
332
-
333
306
pub use rayon:: iter:: ParallelIterator ;
334
307
use rayon:: iter:: IntoParallelIterator ;
335
308
@@ -364,6 +337,49 @@ cfg_if! {
364
337
}
365
338
}
366
339
340
+ #[ derive( Debug ) ]
341
+ pub enum WorkerLocal < T > {
342
+ SingleThread ( T ) ,
343
+ Rayon ( rayon_core:: WorkerLocal < T > ) ,
344
+ }
345
+
346
+ impl < T > WorkerLocal < T > {
347
+ /// Creates a new worker local where the `initial` closure computes the
348
+ /// value this worker local should take for each thread in the thread pool.
349
+ #[ inline]
350
+ pub fn new < F : FnMut ( usize ) -> T > ( mut f : F ) -> WorkerLocal < T > {
351
+ if !PARALLEL . load ( Ordering :: Relaxed ) {
352
+ WorkerLocal :: SingleThread ( f ( 0 ) )
353
+ } else {
354
+ WorkerLocal :: Rayon ( rayon_core:: WorkerLocal :: new ( f) )
355
+ }
356
+ }
357
+
358
+ /// Returns the worker-local value for each thread
359
+ #[ inline]
360
+ pub fn into_inner ( self ) -> Vec < T > {
361
+ match self {
362
+ WorkerLocal :: SingleThread ( inner) => vec ! [ inner] ,
363
+ WorkerLocal :: Rayon ( mt_inner) => mt_inner. into_inner ( ) ,
364
+ }
365
+ }
366
+ }
367
+
368
+ impl < T > Deref for WorkerLocal < T > {
369
+ type Target = T ;
370
+
371
+ #[ inline( always) ]
372
+ fn deref ( & self ) -> & T {
373
+ match self {
374
+ WorkerLocal :: SingleThread ( inner) => inner,
375
+ WorkerLocal :: Rayon ( mt_inner) => mt_inner. deref ( ) ,
376
+ }
377
+ }
378
+ }
379
+
380
+ // Just for speed test
381
+ unsafe impl < T : Send > std:: marker:: Sync for WorkerLocal < T > { }
382
+
367
383
pub fn assert_sync < T : ?Sized + Sync > ( ) { }
368
384
pub fn assert_send < T : ?Sized + Send > ( ) { }
369
385
pub fn assert_send_val < T : ?Sized + Send > ( _t : & T ) { }
0 commit comments