Skip to content

Commit 022dff4

Browse files
committed
Add a Rayon thread pool
1 parent 3df1996 commit 022dff4

File tree

13 files changed

+431
-345
lines changed

13 files changed

+431
-345
lines changed

src/librustc/session/mod.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -869,10 +869,16 @@ impl Session {
869869
ret
870870
}
871871

872+
/// Returns the number of query threads that should be used for this
873+
/// compilation
874+
pub fn query_threads_from_opts(opts: &config::Options) -> usize {
875+
opts.debugging_opts.query_threads.unwrap_or(1)
876+
}
877+
872878
/// Returns the number of query threads that should be used for this
873879
/// compilation
874880
pub fn query_threads(&self) -> usize {
875-
self.opts.debugging_opts.query_threads.unwrap_or(1)
881+
Self::query_threads_from_opts(&self.opts)
876882
}
877883

878884
/// Returns the number of codegen units that should be used for this

src/librustc/ty/context.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1800,9 +1800,11 @@ pub mod tls {
18001800
/// in librustc otherwise. It is used to when diagnostic messages are
18011801
/// emitted and stores them in the current query, if there is one.
18021802
fn track_diagnostic(diagnostic: &Diagnostic) {
1803-
with_context(|context| {
1804-
if let Some(ref query) = context.query {
1805-
query.diagnostics.lock().push(diagnostic.clone());
1803+
with_context_opt(|icx| {
1804+
if let Some(icx) = icx {
1805+
if let Some(ref query) = icx.query {
1806+
query.diagnostics.lock().push(diagnostic.clone());
1807+
}
18061808
}
18071809
})
18081810
}

src/librustc_driver/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ arena = { path = "../libarena" }
1313
graphviz = { path = "../libgraphviz" }
1414
log = "0.4"
1515
env_logger = { version = "0.5", default-features = false }
16+
rustc-rayon = "0.1.0"
17+
scoped-tls = { version = "0.1.1", features = ["nightly"] }
1618
rustc = { path = "../librustc" }
1719
rustc_allocator = { path = "../librustc_allocator" }
1820
rustc_target = { path = "../librustc_target" }

src/librustc_driver/driver.rs

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ use std::fs;
4949
use std::io::{self, Write};
5050
use std::iter;
5151
use std::path::{Path, PathBuf};
52-
use rustc_data_structures::sync::Lrc;
52+
use rustc_data_structures::sync::{self, Lrc};
5353
use std::sync::mpsc;
5454
use syntax::{self, ast, attr, diagnostics, visit};
5555
use syntax::ext::base::ExtCtxt;
@@ -64,6 +64,51 @@ use pretty::ReplaceBodyWithLoop;
6464

6565
use profile;
6666

67+
#[cfg(not(parallel_queries))]
68+
pub fn spawn_thread_pool<F: FnOnce(config::Options) -> R + sync::Send, R: sync::Send>(
69+
opts: config::Options,
70+
f: F
71+
) -> R {
72+
f(opts)
73+
}
74+
75+
#[cfg(parallel_queries)]
76+
pub fn spawn_thread_pool<F: FnOnce(config::Options) -> R + sync::Send, R: sync::Send>(
77+
opts: config::Options,
78+
f: F
79+
) -> R {
80+
use syntax;
81+
use syntax_pos;
82+
use rayon::{ThreadPoolBuilder, ThreadPool};
83+
84+
let config = ThreadPoolBuilder::new().num_threads(Session::query_threads_from_opts(&opts))
85+
.stack_size(16 * 1024 * 1024);
86+
87+
let with_pool = move |pool: &ThreadPool| {
88+
pool.install(move || f(opts))
89+
};
90+
91+
syntax::GLOBALS.with(|syntax_globals| {
92+
syntax_pos::GLOBALS.with(|syntax_pos_globals| {
93+
// The main handler run for each Rayon worker thread and sets up
94+
// the thread local rustc uses. syntax_globals and syntax_pos_globals are
95+
// captured and set on the new threads. ty::tls::with_thread_locals sets up
96+
// thread local callbacks from libsyntax
97+
let main_handler = move |worker: &mut FnMut()| {
98+
syntax::GLOBALS.set(syntax_globals, || {
99+
syntax_pos::GLOBALS.set(syntax_pos_globals, || {
100+
ty::tls::with_thread_locals(|| {
101+
worker()
102+
})
103+
})
104+
})
105+
};
106+
107+
ThreadPool::scoped_pool(config, main_handler, with_pool).unwrap()
108+
})
109+
})
110+
}
111+
67112
pub fn compile_input(
68113
trans: Box<TransCrate>,
69114
sess: &Session,

src/librustc_driver/lib.rs

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ extern crate graphviz;
3535
extern crate env_logger;
3636
#[cfg(unix)]
3737
extern crate libc;
38+
extern crate rustc_rayon as rayon;
3839
extern crate rustc;
3940
extern crate rustc_allocator;
4041
extern crate rustc_target;
@@ -53,6 +54,7 @@ extern crate rustc_save_analysis;
5354
extern crate rustc_traits;
5455
extern crate rustc_trans_utils;
5556
extern crate rustc_typeck;
57+
extern crate scoped_tls;
5658
extern crate serialize;
5759
#[macro_use]
5860
extern crate log;
@@ -66,7 +68,7 @@ use pretty::{PpMode, UserIdentifiedItem};
6668
use rustc_resolve as resolve;
6769
use rustc_save_analysis as save;
6870
use rustc_save_analysis::DumpHandler;
69-
use rustc_data_structures::sync::Lrc;
71+
use rustc_data_structures::sync::{self, Lrc};
7072
use rustc_data_structures::OnDrop;
7173
use rustc::session::{self, config, Session, build_session, CompileResult};
7274
use rustc::session::CompileIncomplete;
@@ -450,36 +452,40 @@ fn get_trans_sysroot(backend_name: &str) -> fn() -> Box<TransCrate> {
450452
// See comments on CompilerCalls below for details about the callbacks argument.
451453
// The FileLoader provides a way to load files from sources other than the file system.
452454
pub fn run_compiler<'a>(args: &[String],
453-
callbacks: &mut CompilerCalls<'a>,
455+
callbacks: &mut (CompilerCalls<'a> + sync::Send),
454456
file_loader: Option<Box<FileLoader + Send + Sync + 'static>>,
455457
emitter_dest: Option<Box<Write + Send>>)
456458
-> (CompileResult, Option<Session>)
457459
{
458460
syntax::with_globals(|| {
459-
run_compiler_impl(args, callbacks, file_loader, emitter_dest)
461+
let matches = match handle_options(args) {
462+
Some(matches) => matches,
463+
None => return (Ok(()), None),
464+
};
465+
466+
let (sopts, cfg) = config::build_session_options_and_crate_config(&matches);
467+
468+
driver::spawn_thread_pool(sopts, |sopts| {
469+
run_compiler_with_pool(matches, sopts, cfg, callbacks, file_loader, emitter_dest)
470+
})
460471
})
461472
}
462473

463-
fn run_compiler_impl<'a>(args: &[String],
464-
callbacks: &mut CompilerCalls<'a>,
465-
file_loader: Option<Box<FileLoader + Send + Sync + 'static>>,
466-
emitter_dest: Option<Box<Write + Send>>)
467-
-> (CompileResult, Option<Session>)
468-
{
474+
fn run_compiler_with_pool<'a>(
475+
matches: getopts::Matches,
476+
sopts: config::Options,
477+
cfg: ast::CrateConfig,
478+
callbacks: &mut (CompilerCalls<'a> + sync::Send),
479+
file_loader: Option<Box<FileLoader + Send + Sync + 'static>>,
480+
emitter_dest: Option<Box<Write + Send>>
481+
) -> (CompileResult, Option<Session>) {
469482
macro_rules! do_or_return {($expr: expr, $sess: expr) => {
470483
match $expr {
471484
Compilation::Stop => return (Ok(()), $sess),
472485
Compilation::Continue => {}
473486
}
474487
}}
475488

476-
let matches = match handle_options(args) {
477-
Some(matches) => matches,
478-
None => return (Ok(()), None),
479-
};
480-
481-
let (sopts, cfg) = config::build_session_options_and_crate_config(&matches);
482-
483489
let descriptions = diagnostics_registry();
484490

485491
do_or_return!(callbacks.early_callback(&matches,

src/librustc_driver/test.rs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -99,20 +99,25 @@ fn test_env<F>(source_string: &str,
9999
where F: FnOnce(Env)
100100
{
101101
syntax::with_globals(|| {
102-
test_env_impl(source_string, args, body)
102+
let mut options = config::basic_options();
103+
options.debugging_opts.verbose = true;
104+
options.unstable_features = UnstableFeatures::Allow;
105+
106+
driver::spawn_thread_pool(options, |options| {
107+
test_env_with_pool(options, source_string, args, body)
108+
})
103109
});
104110
}
105111

106-
fn test_env_impl<F>(source_string: &str,
107-
(emitter, expected_err_count): (Box<Emitter + sync::Send>, usize),
108-
body: F)
112+
fn test_env_with_pool<F>(
113+
options: config::Options,
114+
source_string: &str,
115+
(emitter, expected_err_count): (Box<Emitter + sync::Send>, usize),
116+
body: F
117+
)
109118
where F: FnOnce(Env)
110119
{
111-
let mut options = config::basic_options();
112-
options.debugging_opts.verbose = true;
113-
options.unstable_features = UnstableFeatures::Allow;
114120
let diagnostic_handler = errors::Handler::with_emitter(true, false, emitter);
115-
116121
let sess = session::build_session_(options,
117122
None,
118123
diagnostic_handler,

src/librustdoc/clean/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -697,7 +697,7 @@ impl<'a> FromIterator<&'a DocFragment> for String {
697697
pub struct Attributes {
698698
pub doc_strings: Vec<DocFragment>,
699699
pub other_attrs: Vec<ast::Attribute>,
700-
pub cfg: Option<Rc<Cfg>>,
700+
pub cfg: Option<Arc<Cfg>>,
701701
pub span: Option<syntax_pos::Span>,
702702
/// map from Rust paths to resolved defs and potential URL fragments
703703
pub links: Vec<(String, Option<DefId>, Option<String>)>,
@@ -848,7 +848,7 @@ impl Attributes {
848848
Attributes {
849849
doc_strings,
850850
other_attrs,
851-
cfg: if cfg == Cfg::True { None } else { Some(Rc::new(cfg)) },
851+
cfg: if cfg == Cfg::True { None } else { Some(Arc::new(cfg)) },
852852
span: sp,
853853
links: vec![],
854854
}

0 commit comments

Comments
 (0)