Skip to content

Commit

Permalink
Auto merge of #56813 - oli-obk:main_🧶, r=pnkfelix
Browse files Browse the repository at this point in the history
Always run rustc in a thread

cc @ishitatsuyuki @eddyb

r? @pnkfelix

[Previously](#48575) we moved to only producing threads when absolutely necessary. Even before we opted to only create threads in some cases, which [is unsound](#48575 (comment)) due to the way we use thread local storage.
  • Loading branch information
bors committed Dec 21, 2018
2 parents 6d34ec1 + 6b96827 commit 01c6ea2
Show file tree
Hide file tree
Showing 8 changed files with 5 additions and 103 deletions.
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 @@ -1481,69 +1480,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() {
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 @@ -121,7 +121,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() {}
}

0 comments on commit 01c6ea2

Please sign in to comment.