Skip to content

Commit 296695b

Browse files
committed
Add ThreadLocal
1 parent 1091c65 commit 296695b

File tree

5 files changed

+66
-7
lines changed

5 files changed

+66
-7
lines changed

src/librustc/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#![deny(warnings)]
4242

4343
#![feature(asm)]
44+
#![feature(attr_literals)]
4445
#![feature(box_patterns)]
4546
#![feature(box_syntax)]
4647
#![feature(conservative_impl_trait)]
@@ -64,6 +65,7 @@
6465
#![feature(nonzero)]
6566
#![feature(quote)]
6667
#![feature(refcell_replace_swap)]
68+
#![cfg_attr(stage0, feature(repr_align))]
6769
#![feature(rustc_diagnostic_macros)]
6870
#![feature(set_stdio)]
6971
#![feature(slice_patterns)]

src/librustc/util/common.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,53 @@ use std::hash::{Hash, BuildHasher};
2020
use std::iter::repeat;
2121
use std::path::Path;
2222
use std::time::{Duration, Instant};
23+
use std::cell::UnsafeCell;
2324

2425
use std::sync::mpsc::{Sender};
2526
use syntax_pos::{SpanData};
2627
use ty::maps::{QueryMsg};
2728
use dep_graph::{DepNode};
29+
use rayon_core::registry::Registry;
30+
31+
scoped_thread_local!(pub static THREAD_INDEX: usize);
32+
33+
#[repr(align(64))]
34+
struct CacheAligned<T>(T);
35+
36+
// FIXME: Find a way to ensure this isn't transferred between multiple thread pools
37+
// Thread pools should be the only thing that has a valid THREAD_INDEX.
38+
// Make it contain a Arc<rayon::Registry> and get the index based on the current worker?
39+
pub struct ThreadLocal<T>(Vec<CacheAligned<UnsafeCell<T>>>);
40+
41+
unsafe impl<T> Send for ThreadLocal<T> {}
42+
unsafe impl<T> Sync for ThreadLocal<T> {}
43+
44+
impl<T> ThreadLocal<T> {
45+
pub fn new<F>(f: F) -> ThreadLocal<T>
46+
where F: Fn() -> T,
47+
{
48+
let n = Registry::current_num_threads();
49+
ThreadLocal((0..(1 + n)).map(|_| CacheAligned(UnsafeCell::new(f()))).collect())
50+
}
51+
52+
pub fn into_inner(self) -> Vec<T> {
53+
self.0.into_iter().map(|c| c.0.into_inner()).collect()
54+
}
55+
56+
pub fn current(&self) -> &mut T {
57+
use std::ops::Index;
58+
59+
unsafe {
60+
&mut *(self.0.index(THREAD_INDEX.with(|t| *t)).0.get())
61+
}
62+
}
63+
}
64+
65+
impl<T> ThreadLocal<Vec<T>> {
66+
pub fn collect(self) -> Vec<T> {
67+
self.into_inner().into_iter().flat_map(|v| v).collect()
68+
}
69+
}
2870

2971
// The name of the associated type for `Fn` return types
3072
pub const FN_OUTPUT_NAME: &'static str = "Output";

src/librustc_driver/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ graphviz = { path = "../libgraphviz" }
1414
log = "0.4"
1515
env_logger = { version = "0.4", default-features = false }
1616
rayon = { git = "https://github.com/Zoxc/rayon.git", branch = "fiber" }
17+
rayon-core = { git = "https://github.com/Zoxc/rayon.git", branch = "fiber" }
1718
scoped-tls = { git = "https://github.com/Zoxc/scoped-tls.git", features=["nightly"] }
1819
rustc = { path = "../librustc" }
1920
rustc_allocator = { path = "../librustc_allocator" }

src/librustc_driver/driver.rs

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,11 @@ use profile;
6868

6969
#[cfg(not(parallel_queries))]
7070
pub fn spawn_thread_pool<F: FnOnce(Arc<Mutex<usize>>) -> R, R>(_: &Session, f: F) -> R {
71-
f(Arc::new(Mutex::new(0)))
71+
use rustc::util::common::THREAD_INDEX;
72+
73+
THREAD_INDEX.set(&0, || {
74+
f(Arc::new(Mutex::new(0)))
75+
})
7276
}
7377

7478
#[cfg(parallel_queries)]
@@ -78,6 +82,8 @@ pub fn spawn_thread_pool<F: FnOnce(Arc<Mutex<usize>>) -> R, R>(sess: &Session, f
7882
use syntax_pos;
7983
use scoped_tls::ScopedKey;
8084
use rayon::{Configuration, ThreadPool};
85+
use rayon_core;
86+
use rustc::util::common::THREAD_INDEX;
8187

8288
let gcx_ptr = Arc::new(Mutex::new(0));
8389

@@ -90,7 +96,9 @@ pub fn spawn_thread_pool<F: FnOnce(Arc<Mutex<usize>>) -> R, R>(sess: &Session, f
9096

9197
let with_pool = move |pool: &ThreadPool| {
9298
pool.with_global_registry(|| {
93-
f(arg_gcx_ptr)
99+
THREAD_INDEX.set(&0, || {
100+
f(arg_gcx_ptr)
101+
})
94102
})
95103
};
96104

@@ -119,11 +127,16 @@ pub fn spawn_thread_pool<F: FnOnce(Arc<Mutex<usize>>) -> R, R>(sess: &Session, f
119127
try_with(&syntax::GLOBALS, |syntax_globals| {
120128
try_with(&syntax_pos::GLOBALS, |syntax_pos_globals| {
121129
let main_handler = move |worker: &mut FnMut()| {
122-
maybe_set(&PROFQ_CHAN, prof_chan, || {
123-
maybe_set(&syntax::GLOBALS, syntax_globals, || {
124-
maybe_set(&syntax_pos::GLOBALS, syntax_pos_globals, || {
125-
ty::tls::with_thread_locals(|| {
126-
worker()
130+
let idx = unsafe {
131+
1 + (*rayon_core::registry::WorkerThread::current()).index()
132+
};
133+
THREAD_INDEX.set(&idx, || {
134+
maybe_set(&PROFQ_CHAN, prof_chan, || {
135+
maybe_set(&syntax::GLOBALS, syntax_globals, || {
136+
maybe_set(&syntax_pos::GLOBALS, syntax_pos_globals, || {
137+
ty::tls::with_thread_locals(|| {
138+
worker()
139+
})
127140
})
128141
})
129142
})

src/librustc_driver/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ extern crate env_logger;
3434
#[cfg(unix)]
3535
extern crate libc;
3636
extern crate rayon;
37+
extern crate rayon_core;
3738
extern crate rustc;
3839
extern crate rustc_allocator;
3940
extern crate rustc_back;

0 commit comments

Comments
 (0)