From 4dfb91d238bc1f43ae9494d6fa9fa23697bb5630 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Fri, 14 Dec 2018 13:09:05 +0100 Subject: [PATCH 1/2] Always run rustc in a thread --- src/librustc_driver/lib.rs | 66 +++----------------------------------- 1 file changed, 5 insertions(+), 61 deletions(-) diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 41c9b22afe06f..cec0f31819d7d 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -1482,69 +1482,13 @@ pub fn in_named_rustc_thread(name: String, f: F) -> Result 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); } From 6b96827ae971cec1f1bf83245d8356481e76b644 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Fri, 14 Dec 2018 17:03:45 +0100 Subject: [PATCH 2/2] Remove dead code --- src/librustc_driver/lib.rs | 1 - src/libstd/rt.rs | 15 --------------- src/libstd/sys/cloudabi/thread.rs | 1 - src/libstd/sys/redox/thread.rs | 1 - src/libstd/sys/sgx/thread.rs | 1 - src/libstd/sys/unix/thread.rs | 21 --------------------- src/libstd/sys/wasm/thread.rs | 1 - src/libstd/sys/windows/thread.rs | 1 - 8 files changed, 42 deletions(-) diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index cec0f31819d7d..013085c156ee0 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -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"] diff --git a/src/libstd/rt.rs b/src/libstd/rt.rs index 9e957bd87d79e..fdaf2a821faad 100644 --- a/src/libstd/rt.rs +++ b/src/libstd/rt.rs @@ -73,18 +73,3 @@ fn lang_start { 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); -} diff --git a/src/libstd/sys/cloudabi/thread.rs b/src/libstd/sys/cloudabi/thread.rs index a76e1fa3345cd..54c79114be490 100644 --- a/src/libstd/sys/cloudabi/thread.rs +++ b/src/libstd/sys/cloudabi/thread.rs @@ -119,7 +119,6 @@ pub mod guard { pub unsafe fn init() -> Option { None } - pub unsafe fn deinit() {} } fn min_stack_size(_: *const libc::pthread_attr_t) -> usize { diff --git a/src/libstd/sys/redox/thread.rs b/src/libstd/sys/redox/thread.rs index ff86180538283..ca014fd576bd3 100644 --- a/src/libstd/sys/redox/thread.rs +++ b/src/libstd/sys/redox/thread.rs @@ -92,5 +92,4 @@ pub mod guard { pub type Guard = !; pub unsafe fn current() -> Option { None } pub unsafe fn init() -> Option { None } - pub unsafe fn deinit() {} } diff --git a/src/libstd/sys/sgx/thread.rs b/src/libstd/sys/sgx/thread.rs index 9de12a5e6f154..9f3c4536cb5b6 100644 --- a/src/libstd/sys/sgx/thread.rs +++ b/src/libstd/sys/sgx/thread.rs @@ -97,5 +97,4 @@ pub mod guard { pub type Guard = !; pub unsafe fn current() -> Option { None } pub unsafe fn init() -> Option { None } - pub unsafe fn deinit() {} } diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs index 4ff060018ae33..e0d2c620498b6 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -211,7 +211,6 @@ pub mod guard { pub type Guard = Range; pub unsafe fn current() -> Option { None } pub unsafe fn init() -> Option { None } - pub unsafe fn deinit() {} } @@ -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", diff --git a/src/libstd/sys/wasm/thread.rs b/src/libstd/sys/wasm/thread.rs index 3d74ffdc14a59..f9abb0b825a34 100644 --- a/src/libstd/sys/wasm/thread.rs +++ b/src/libstd/sys/wasm/thread.rs @@ -68,7 +68,6 @@ pub mod guard { pub type Guard = !; pub unsafe fn current() -> Option { None } pub unsafe fn init() -> Option { None } - pub unsafe fn deinit() {} } cfg_if! { diff --git a/src/libstd/sys/windows/thread.rs b/src/libstd/sys/windows/thread.rs index 1a97dd10ced8d..621ae2fda58c3 100644 --- a/src/libstd/sys/windows/thread.rs +++ b/src/libstd/sys/windows/thread.rs @@ -98,5 +98,4 @@ pub mod guard { pub type Guard = !; pub unsafe fn current() -> Option { None } pub unsafe fn init() -> Option { None } - pub unsafe fn deinit() {} }