Skip to content

Commit e85c922

Browse files
committed
rustc_driver: get rid of extra thread on Unix
1 parent 8aa27ee commit e85c922

File tree

3 files changed

+55
-8
lines changed

3 files changed

+55
-8
lines changed

src/librustc_driver/lib.rs

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#![feature(quote)]
2525
#![feature(rustc_diagnostic_macros)]
2626
#![feature(set_stdio)]
27+
#![feature(rustc_stack_internals)]
2728

2829
extern crate arena;
2930
extern crate getopts;
@@ -1461,16 +1462,50 @@ pub fn in_rustc_thread<F, R>(f: F) -> Result<R, Box<Any + Send>>
14611462
// Temporarily have stack size set to 16MB to deal with nom-using crates failing
14621463
const STACK_SIZE: usize = 16 * 1024 * 1024; // 16MB
14631464

1464-
let mut cfg = thread::Builder::new().name("rustc".to_string());
1465+
#[cfg(unix)]
1466+
let spawn_thread = unsafe {
1467+
// Fetch the current resource limits
1468+
let mut rlim = libc::rlimit {
1469+
rlim_cur: 0,
1470+
rlim_max: 0,
1471+
};
1472+
if libc::getrlimit(libc::RLIMIT_STACK, &mut rlim) != 0 {
1473+
let err = io::Error::last_os_error();
1474+
error!("in_rustc_thread: error calling getrlimit: {}", err);
1475+
true
1476+
} else if rlim.rlim_max < STACK_SIZE as libc::rlim_t {
1477+
true
1478+
} else {
1479+
rlim.rlim_cur = STACK_SIZE as libc::rlim_t;
1480+
if libc::setrlimit(libc::RLIMIT_STACK, &mut rlim) != 0 {
1481+
let err = io::Error::last_os_error();
1482+
error!("in_rustc_thread: error calling setrlimit: {}", err);
1483+
true
1484+
} else {
1485+
std::thread::update_stack_guard();
1486+
false
1487+
}
1488+
}
1489+
};
14651490

1466-
// FIXME: Hacks on hacks. If the env is trying to override the stack size
1467-
// then *don't* set it explicitly.
1468-
if env::var_os("RUST_MIN_STACK").is_none() {
1469-
cfg = cfg.stack_size(STACK_SIZE);
1470-
}
1491+
#[cfg(not(unix))]
1492+
let spawn_thread = true;
1493+
1494+
// The or condition is added from backward compatibility.
1495+
if spawn_thread || env::var_os("RUST_MIN_STACK").is_some() {
1496+
let mut cfg = thread::Builder::new().name("rustc".to_string());
1497+
1498+
// FIXME: Hacks on hacks. If the env is trying to override the stack size
1499+
// then *don't* set it explicitly.
1500+
if env::var_os("RUST_MIN_STACK").is_none() {
1501+
cfg = cfg.stack_size(STACK_SIZE);
1502+
}
14711503

1472-
let thread = cfg.spawn(f);
1473-
thread.unwrap().join()
1504+
let thread = cfg.spawn(f);
1505+
thread.unwrap().join()
1506+
} else {
1507+
Ok(f())
1508+
}
14741509
}
14751510

14761511
/// Get a list of extra command-line flags provided by the user, as strings.

src/libstd/sys_common/thread_info.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,7 @@ pub fn set(stack_guard: Option<Guard>, thread: Thread) {
5050
thread,
5151
}));
5252
}
53+
54+
pub fn reset_guard(stack_guard: Option<Guard>) {
55+
THREAD_INFO.with(move |c| c.borrow_mut().as_mut().unwrap().stack_guard = stack_guard);
56+
}

src/libstd/thread/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,14 @@ pub use self::local::{LocalKey, AccessError};
208208
#[unstable(feature = "libstd_thread_internals", issue = "0")]
209209
#[doc(hidden)] pub use self::local::os::Key as __OsLocalKeyInner;
210210

211+
/// Function used for resetting the main stack guard address after setrlimit().
212+
/// This is POSIX specific and unlikely to be directly stabilized.
213+
#[unstable(feature = "rustc_stack_internals", issue = "0")]
214+
pub unsafe fn update_stack_guard() {
215+
let main_guard = imp::guard::init();
216+
thread_info::reset_guard(main_guard);
217+
}
218+
211219
////////////////////////////////////////////////////////////////////////////////
212220
// Builder
213221
////////////////////////////////////////////////////////////////////////////////

0 commit comments

Comments
 (0)