Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Always run rustc in a thread #56813

Merged
merged 2 commits into from
Dec 21, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 5 additions & 62 deletions src/librustc_driver/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
#![feature(rustc_diagnostic_macros)]
#![feature(slice_sort_by_cached_key)]
#![feature(set_stdio)]
#![feature(rustc_stack_internals)]
#![feature(no_debug)]

#![recursion_limit="256"]
Expand Down Expand Up @@ -1482,69 +1481,13 @@ pub fn in_named_rustc_thread<F, R>(name: String, f: F) -> Result<R, Box<dyn Any
where F: FnOnce() -> R + Send + 'static,
R: Send + 'static,
{
#[cfg(all(unix, not(target_os = "haiku")))]
let spawn_thread = unsafe {
// Fetch the current resource limits
let mut rlim = libc::rlimit {
rlim_cur: 0,
rlim_max: 0,
};
if libc::getrlimit(libc::RLIMIT_STACK, &mut rlim) != 0 {
let err = io::Error::last_os_error();
error!("in_rustc_thread: error calling getrlimit: {}", err);
true
} else if rlim.rlim_max < STACK_SIZE as libc::rlim_t {
true
} else if rlim.rlim_cur < STACK_SIZE as libc::rlim_t {
std::rt::deinit_stack_guard();
rlim.rlim_cur = STACK_SIZE as libc::rlim_t;
if libc::setrlimit(libc::RLIMIT_STACK, &mut rlim) != 0 {
let err = io::Error::last_os_error();
error!("in_rustc_thread: error calling setrlimit: {}", err);
std::rt::update_stack_guard();
true
} else {
std::rt::update_stack_guard();
false
}
} else {
false
}
};

// We set the stack size at link time. See src/rustc/rustc.rs.
#[cfg(windows)]
let spawn_thread = false;

#[cfg(target_os = "haiku")]
let spawn_thread = unsafe {
// Haiku does not have setrlimit implemented for the stack size.
// By default it does have the 16 MB stack limit, but we check this in
// case the minimum STACK_SIZE changes or Haiku's defaults change.
let mut rlim = libc::rlimit {
rlim_cur: 0,
rlim_max: 0,
};
if libc::getrlimit(libc::RLIMIT_STACK, &mut rlim) != 0 {
let err = io::Error::last_os_error();
error!("in_rustc_thread: error calling getrlimit: {}", err);
true
} else if rlim.rlim_cur >= STACK_SIZE {
false
} else {
true
}
};

#[cfg(not(any(windows, unix)))]
let spawn_thread = true;

// The or condition is added from backward compatibility.
if spawn_thread || env::var_os("RUST_MIN_STACK").is_some() {
// We need a thread for soundness of thread local storage in rustc. For debugging purposes
// we allow an escape hatch where everything runs on the main thread.
if env::var_os("RUSTC_UNSTABLE_NO_MAIN_THREAD").is_none() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find the idea of using an environment variable here so undiscoverable that the condition might as well be false for all intents and purposes…

The manual page for rustc technically has a section on environment variables. Perhaps it would be a good place to document this envvar there as well?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, does the compiler have a part of its --help -v output dedicated to environment variables? That might be nice too.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(having said that, such additions can wait for a followup PR... lets get this PR in now.)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cc #45495 (and maybe #44074?)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This env var is gone now that #56732 landed.

let mut cfg = thread::Builder::new().name(name);

// FIXME: Hacks on hacks. If the env is trying to override the stack size
// then *don't* set it explicitly.
// If the env is trying to override the stack size then *don't* set it explicitly.
// The libstd thread impl will fetch the `RUST_MIN_STACK` env var itself.
if env::var_os("RUST_MIN_STACK").is_none() {
cfg = cfg.stack_size(STACK_SIZE);
}
Expand Down
15 changes: 0 additions & 15 deletions src/libstd/rt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,18 +73,3 @@ fn lang_start<T: ::process::Termination + 'static>
{
lang_start_internal(&move || main().report(), argc, argv)
}

/// Function used for reverting changes to the main stack before setrlimit().
/// This is POSIX (non-Linux) specific and unlikely to be directly stabilized.
#[unstable(feature = "rustc_stack_internals", issue = "0")]
pub unsafe fn deinit_stack_guard() {
::sys::thread::guard::deinit();
}

/// Function used for resetting the main stack guard address after setrlimit().
/// This is POSIX specific and unlikely to be directly stabilized.
#[unstable(feature = "rustc_stack_internals", issue = "0")]
pub unsafe fn update_stack_guard() {
let main_guard = ::sys::thread::guard::init();
::sys_common::thread_info::reset_guard(main_guard);
}
1 change: 0 additions & 1 deletion src/libstd/sys/cloudabi/thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,6 @@ pub mod guard {
pub unsafe fn init() -> Option<Guard> {
None
}
pub unsafe fn deinit() {}
}

fn min_stack_size(_: *const libc::pthread_attr_t) -> usize {
Expand Down
1 change: 0 additions & 1 deletion src/libstd/sys/redox/thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,5 +92,4 @@ pub mod guard {
pub type Guard = !;
pub unsafe fn current() -> Option<Guard> { None }
pub unsafe fn init() -> Option<Guard> { None }
pub unsafe fn deinit() {}
}
1 change: 0 additions & 1 deletion src/libstd/sys/sgx/thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,5 +97,4 @@ pub mod guard {
pub type Guard = !;
pub unsafe fn current() -> Option<Guard> { None }
pub unsafe fn init() -> Option<Guard> { None }
pub unsafe fn deinit() {}
}
21 changes: 0 additions & 21 deletions src/libstd/sys/unix/thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,6 @@ pub mod guard {
pub type Guard = Range<usize>;
pub unsafe fn current() -> Option<Guard> { None }
pub unsafe fn init() -> Option<Guard> { None }
pub unsafe fn deinit() {}
}


Expand Down Expand Up @@ -355,26 +354,6 @@ pub mod guard {
}
}

pub unsafe fn deinit() {
if !cfg!(target_os = "linux") {
if let Some(stackaddr) = get_stack_start_aligned() {
// Remove the protection on the guard page.
// FIXME: we cannot unmap the page, because when we mmap()
// above it may be already mapped by the OS, which we can't
// detect from mmap()'s return value. If we unmap this page,
// it will lead to failure growing stack size on platforms like
// macOS. Instead, just restore the page to a writable state.
// This ain't Linux, so we probably don't need to care about
// execstack.
let result = mprotect(stackaddr, PAGE_SIZE, PROT_READ | PROT_WRITE);

if result != 0 {
panic!("unable to reset the guard page");
}
}
}
}

#[cfg(any(target_os = "macos",
target_os = "bitrig",
target_os = "openbsd",
Expand Down
1 change: 0 additions & 1 deletion src/libstd/sys/wasm/thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ pub mod guard {
pub type Guard = !;
pub unsafe fn current() -> Option<Guard> { None }
pub unsafe fn init() -> Option<Guard> { None }
pub unsafe fn deinit() {}
}

cfg_if! {
Expand Down
1 change: 0 additions & 1 deletion src/libstd/sys/windows/thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,5 +98,4 @@ pub mod guard {
pub type Guard = !;
pub unsafe fn current() -> Option<Guard> { None }
pub unsafe fn init() -> Option<Guard> { None }
pub unsafe fn deinit() {}
}