Skip to content

Commit bfc072f

Browse files
committed
Added TLS LockLatch with a reset() method.
1 parent 55f235f commit bfc072f

File tree

2 files changed

+28
-15
lines changed

2 files changed

+28
-15
lines changed

rayon-core/src/latch.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,11 @@ impl LockLatch {
8686
}
8787
}
8888

89+
/// Resets this lock latch so it can be reused again.
90+
pub(super) fn reset(&mut self) {
91+
*self.m.lock().unwrap() = false;
92+
}
93+
8994
/// Block until latch is set.
9095
pub(super) fn wait(&self) {
9196
let mut guard = self.m.lock().unwrap();

rayon-core/src/registry.rs

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use std::fmt;
1515
use std::hash::Hasher;
1616
use std::io;
1717
use std::mem;
18+
use std::ops::DerefMut;
1819
use std::ptr;
1920
#[allow(deprecated)]
2021
use std::sync::atomic::ATOMIC_USIZE_INIT;
@@ -486,21 +487,26 @@ impl Registry {
486487
OP: FnOnce(&WorkerThread, bool) -> R + Send,
487488
R: Send,
488489
{
489-
let mut latch = LockLatch::new();
490-
491-
// This thread isn't a member of *any* thread pool, so just block.
492-
debug_assert!(WorkerThread::current().is_null());
493-
let job = StackJob::new(
494-
|injected| {
495-
let worker_thread = WorkerThread::current();
496-
assert!(injected && !worker_thread.is_null());
497-
op(&*worker_thread, true)
498-
},
499-
&mut latch,
500-
);
501-
self.inject(&[job.as_job_ref()]);
502-
job.latch.wait();
503-
job.into_result()
490+
LOCK_LATCH.with(|l| {
491+
// This should not panic since the latch is thread local and we are in the `cold` path.
492+
// If `op` were to call another `ThreadPool::install` it would not end up here.
493+
let mut latch = l.borrow_mut();
494+
495+
// This thread isn't a member of *any* thread pool, so just block.
496+
debug_assert!(WorkerThread::current().is_null());
497+
let job = StackJob::new(
498+
|injected| {
499+
let worker_thread = WorkerThread::current();
500+
assert!(injected && !worker_thread.is_null());
501+
op(&*worker_thread, true)
502+
},
503+
latch.deref_mut(),
504+
);
505+
self.inject(&[job.as_job_ref()]);
506+
job.latch.wait();
507+
job.latch.reset(); // Makes sure we can use the same latch again next time.
508+
job.into_result()
509+
})
504510
}
505511

506512
#[cold]
@@ -613,6 +619,8 @@ pub(super) struct WorkerThread {
613619
// for a RefCell<T> etc.
614620
thread_local! {
615621
static WORKER_THREAD_STATE: Cell<*const WorkerThread> = Cell::new(ptr::null());
622+
623+
static LOCK_LATCH: RefCell<LockLatch> = RefCell::new(LockLatch::new());
616624
}
617625

618626
impl Drop for WorkerThread {

0 commit comments

Comments
 (0)