Skip to content

Commit 2585741

Browse files
committed
wip
1 parent dd50854 commit 2585741

File tree

6 files changed

+58
-11
lines changed

6 files changed

+58
-11
lines changed

src/librustc/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ fmt_macros = { path = "../libfmt_macros" }
1515
graphviz = { path = "../libgraphviz" }
1616
jobserver = "0.1"
1717
lazy_static = "1.0.0"
18+
scoped-tls = { version = "0.1.1", features = ["nightly"] }
1819
log = { version = "0.4", features = ["release_max_level_info", "std"] }
1920
proc_macro = { path = "../libproc_macro" }
2021
rustc-rayon-core = { git = "https://github.com/Zoxc/rayon.git", branch = "rustc" }

src/librustc/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ extern crate fmt_macros;
8484
extern crate getopts;
8585
extern crate graphviz;
8686
#[macro_use] extern crate lazy_static;
87+
#[macro_use] extern crate scoped_tls;
8788
#[cfg(windows)]
8889
extern crate libc;
8990
extern crate rustc_target;

src/librustc/ty/context.rs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1756,7 +1756,7 @@ pub mod tls {
17561756
use rustc_data_structures::OnDrop;
17571757
use rayon_core;
17581758
use dep_graph::OpenTask;
1759-
use rustc_data_structures::sync::{self, Lrc};
1759+
use rustc_data_structures::sync::{self, Lrc, Lock};
17601760

17611761
/// This is the implicit state of rustc. It contains the current
17621762
/// TyCtxt and query. It is updated when creating a local interner or
@@ -1872,6 +1872,13 @@ pub mod tls {
18721872
where F: for<'a> FnOnce(TyCtxt<'a, 'gcx, 'gcx>) -> R
18731873
{
18741874
with_thread_locals(|| {
1875+
GCX_PTR.with(|lock| {
1876+
*lock.lock() = gcx as *const _ as usize;
1877+
});
1878+
let _on_drop = OnDrop(move || {
1879+
GCX_PTR.with(|lock| *lock.lock() = 0);
1880+
});
1881+
18751882
let tcx = TyCtxt {
18761883
gcx,
18771884
interners: &gcx.global_interners,
@@ -1888,6 +1895,25 @@ pub mod tls {
18881895
})
18891896
}
18901897

1898+
scoped_thread_local!(pub static GCX_PTR: Lock<usize>);
1899+
1900+
pub unsafe fn with_global<F, R>(f: F) -> R
1901+
where F: for<'a, 'gcx, 'tcx> FnOnce(TyCtxt<'a, 'gcx, 'tcx>) -> R
1902+
{
1903+
let gcx = &*(GCX_PTR.with(|lock| *lock.lock()) as *const GlobalCtxt<'_>);
1904+
let tcx = TyCtxt {
1905+
gcx,
1906+
interners: &gcx.global_interners,
1907+
};
1908+
let icx = ImplicitCtxt {
1909+
query: None,
1910+
tcx,
1911+
layout_depth: 0,
1912+
task: &OpenTask::Ignore,
1913+
};
1914+
enter_context(&icx, |_| f(tcx))
1915+
}
1916+
18911917
/// Allows access to the current ImplicitCtxt in a closure if one is available
18921918
pub fn with_context_opt<F, R>(f: F) -> R
18931919
where F: for<'a, 'gcx, 'tcx> FnOnce(Option<&ImplicitCtxt<'a, 'gcx, 'tcx>>) -> R

src/librustc/ty/maps/job.rs

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use std::fmt;
2424
use std::collections::HashSet;
2525
#[cfg(parallel_queries)]
2626
use {
27+
rayon_core,
2728
parking_lot::{Mutex, Condvar},
2829
std::sync::atomic::Ordering,
2930
std::thread,
@@ -172,6 +173,7 @@ impl<'a, 'tcx> QueryWaiter<'a, 'tcx> {
172173
::std::thread::current().id(),
173174
tcx.active_threads.load(Ordering::SeqCst),
174175
&self.condvar as *const _ as usize);
176+
rayon_core::unblock();
175177
self.condvar.notify_one();
176178
}
177179
}
@@ -207,14 +209,17 @@ impl QueryLatch {
207209
info.waiters.push(mem::transmute(waiter));
208210
}
209211
if tcx.active_threads.fetch_sub(1, Ordering::SeqCst) == 1 {
212+
/*
210213
// We are the last active thread, waiting here would cause a deadlock.
211214
// Spawn a thread to handle the deadlock before we go to sleep
212215
handle_deadlock(tcx);
216+
*/
213217
}
214218
eprintln!("[{:?}] (await) active threads: {} condvar: {:x}",
215219
::std::thread::current().id(),
216220
tcx.active_threads.load(Ordering::SeqCst),
217221
&waiter.condvar as *const _ as usize);
222+
rayon_core::block();
218223
waiter.condvar.wait(&mut info);
219224
}
220225
}
@@ -442,25 +447,32 @@ fn remove_cycle<'tcx>(
442447
}
443448

444449
#[cfg(parallel_queries)]
445-
fn handle_deadlock(tcx: TyCtxt<'_, '_, '_>) {
450+
pub fn handle_deadlock() {
446451
use syntax;
447452
use syntax_pos;
448453

454+
let gcx_ptr = tls::GCX_PTR.with(|gcx_ptr| {
455+
gcx_ptr as *const _
456+
});
457+
let gcx_ptr = unsafe { &*gcx_ptr };
458+
449459
let syntax_globals = syntax::GLOBALS.with(|syntax_globals| {
450460
syntax_globals as *const _
451461
});
452462
let syntax_globals = unsafe { &*syntax_globals };
463+
453464
let syntax_pos_globals = syntax_pos::GLOBALS.with(|syntax_pos_globals| {
454465
syntax_pos_globals as *const _
455466
});
456467
let syntax_pos_globals = unsafe { &*syntax_pos_globals };
457-
let tcx: TyCtxt<'static, 'static, 'static> = unsafe { mem::transmute(tcx) };
458468
thread::spawn(move || {
459-
syntax::GLOBALS.set(syntax_globals, || {
469+
tls::GCX_PTR.set(gcx_ptr, || {
460470
syntax_pos::GLOBALS.set(syntax_pos_globals, || {
461-
tls::with_thread_locals(|| {
462-
tls::enter_global(&*tcx, |_| {
463-
deadlock(tcx)
471+
syntax_pos::GLOBALS.set(syntax_pos_globals, || {
472+
tls::with_thread_locals(|| {
473+
unsafe {
474+
tls::with_global(|tcx| deadlock(tcx))
475+
}
464476
})
465477
})
466478
})

src/librustc/ty/maps/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ use self::plumbing::*;
6666
pub use self::plumbing::{force_from_dep_node, CycleError};
6767

6868
mod job;
69-
pub use self::job::{QueryJob, QueryInfo};
69+
pub use self::job::{QueryJob, QueryInfo, handle_deadlock};
7070

7171
mod keys;
7272
pub use self::keys::Key;

src/librustc_driver/driver.rs

Lines changed: 10 additions & 3 deletions
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::{self, Lrc};
52+
use rustc_data_structures::sync::{self, Lrc, Lock};
5353
use std::sync::mpsc;
5454
use syntax::{self, ast, attr, diagnostics, visit};
5555
use syntax::ext::base::ExtCtxt;
@@ -69,7 +69,9 @@ pub fn spawn_thread_pool<F: FnOnce(config::Options) -> R + sync::Send, R: sync::
6969
opts: config::Options,
7070
f: F
7171
) -> R {
72-
f(opts)
72+
ty::tls::GCX_PTR.set(&Lock::new(0), || {
73+
f(opts)
74+
})
7375
}
7476

7577
#[cfg(parallel_queries)]
@@ -81,7 +83,10 @@ pub fn spawn_thread_pool<F: FnOnce(config::Options) -> R + sync::Send, R: sync::
8183
use syntax_pos;
8284
use rayon::{ThreadPoolBuilder, ThreadPool};
8385

86+
let gcx_ptr = &Lock::new(0);
87+
8488
let config = ThreadPoolBuilder::new().num_threads(Session::query_threads_from_opts(&opts))
89+
.deadlock_handler(ty::maps::handle_deadlock)
8590
.stack_size(16 * 1024 * 1024);
8691

8792
let with_pool = move |pool: &ThreadPool| {
@@ -98,7 +103,9 @@ pub fn spawn_thread_pool<F: FnOnce(config::Options) -> R + sync::Send, R: sync::
98103
syntax::GLOBALS.set(syntax_globals, || {
99104
syntax_pos::GLOBALS.set(syntax_pos_globals, || {
100105
ty::tls::with_thread_locals(|| {
101-
worker()
106+
ty::tls::GCX_PTR.set(gcx_ptr, || {
107+
worker()
108+
})
102109
})
103110
})
104111
})

0 commit comments

Comments
 (0)