]> git.lizzy.rs Git - rust.git/commitdiff
rustc_driver: get rid of extra thread on Unix
authorTatsuyuki Ishi <ishitatsuyuki@gmail.com>
Tue, 27 Feb 2018 07:51:12 +0000 (16:51 +0900)
committerTatsuyuki Ishi <ishitatsuyuki@gmail.com>
Sun, 18 Mar 2018 14:05:28 +0000 (23:05 +0900)
src/librustc_driver/lib.rs
src/libstd/sys_common/thread_info.rs
src/libstd/thread/mod.rs

index f1f3a0519bbcb2044bb4f1db598695073a0fa532..8605764497a168dcabeb17653bb0405d7b9d92fe 100644 (file)
@@ -24,6 +24,7 @@
 #![feature(quote)]
 #![feature(rustc_diagnostic_macros)]
 #![feature(set_stdio)]
+#![feature(rustc_stack_internals)]
 
 extern crate arena;
 extern crate getopts;
@@ -1461,16 +1462,50 @@ pub fn in_rustc_thread<F, R>(f: F) -> Result<R, Box<Any + Send>>
     // Temporarily have stack size set to 16MB to deal with nom-using crates failing
     const STACK_SIZE: usize = 16 * 1024 * 1024; // 16MB
 
-    let mut cfg = thread::Builder::new().name("rustc".to_string());
+    #[cfg(unix)]
+    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 {
+            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);
+                true
+            } else {
+                std::thread::update_stack_guard();
+                false
+            }
+        }
+    };
 
-    // FIXME: Hacks on hacks. If the env is trying to override the stack size
-    // then *don't* set it explicitly.
-    if env::var_os("RUST_MIN_STACK").is_none() {
-        cfg = cfg.stack_size(STACK_SIZE);
-    }
+    #[cfg(not(unix))]
+    let spawn_thread = true;
+
+    // The or condition is added from backward compatibility.
+    if spawn_thread || env::var_os("RUST_MIN_STACK").is_some() {
+        let mut cfg = thread::Builder::new().name("rustc".to_string());
+
+        // FIXME: Hacks on hacks. If the env is trying to override the stack size
+        // then *don't* set it explicitly.
+        if env::var_os("RUST_MIN_STACK").is_none() {
+            cfg = cfg.stack_size(STACK_SIZE);
+        }
 
-    let thread = cfg.spawn(f);
-    thread.unwrap().join()
+        let thread = cfg.spawn(f);
+        thread.unwrap().join()
+    } else {
+        Ok(f())
+    }
 }
 
 /// Get a list of extra command-line flags provided by the user, as strings.
index 6a2b6742367a5b4ce6032cfe943b9708fb9b9da9..d75cbded7347b2936d03b0ac571b93e2902d63e2 100644 (file)
@@ -50,3 +50,7 @@ pub fn set(stack_guard: Option<Guard>, thread: Thread) {
         thread,
     }));
 }
+
+pub fn reset_guard(stack_guard: Option<Guard>) {
+    THREAD_INFO.with(move |c| c.borrow_mut().as_mut().unwrap().stack_guard = stack_guard);
+}
index 71aee673cfe3ee57e7893a54c1e1823493713693..b686ddc205ea7865cca72ab7354c8e519ea53e62 100644 (file)
 #[unstable(feature = "libstd_thread_internals", issue = "0")]
 #[doc(hidden)] pub use self::local::os::Key as __OsLocalKeyInner;
 
+/// 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 = imp::guard::init();
+    thread_info::reset_guard(main_guard);
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // Builder
 ////////////////////////////////////////////////////////////////////////////////