about summary refs log tree commit diff
path: root/src/libstd/rt
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-11-21 03:41:45 +0000
committerbors <bors@rust-lang.org>2014-11-21 03:41:45 +0000
commitc9f6d696420107f82304b992cf623b806995fe18 (patch)
treed2224bd566aaf93132fb5a959e0ba33192bde035 /src/libstd/rt
parent98300516072c6afd0e93654b325f5924b60dea53 (diff)
parent32c3d027801b8f30f741b1b5340682e7009d02ac (diff)
downloadrust-c9f6d696420107f82304b992cf623b806995fe18.tar.gz
rust-c9f6d696420107f82304b992cf623b806995fe18.zip
auto merge of #18967 : aturon/rust/remove-runtime, r=alexcrichton
This PR completes the removal of the runtime system and green-threaded abstractions as part of implementing [RFC 230](https://github.com/rust-lang/rfcs/pull/230).

Specifically:

* It removes the `Runtime` trait, welding the scheduling infrastructure directly to native threads.

* It removes `libgreen` and `libnative` entirely.

* It rewrites `sync::mutex` as a trivial layer on top of native mutexes. Eventually, the two modules will be merged.

* It hides the vast majority of `std::rt`.

This completes the basic task of removing the runtime system (I/O and scheduling) and components that depend on it. 

After this lands, a follow-up PR will pull the `rustrt` crate back into `std`, turn `std::task` into `std::thread` (with API changes to go along with it), and completely cut out the remaining startup/teardown sequence. Other changes, including new [TLS](https://github.com/rust-lang/rfcs/pull/461) and synchronization are in the RFC or pre-RFC phase.

Closes #17325
Closes #18687

[breaking-change]

r? @alexcrichton 
Diffstat (limited to 'src/libstd/rt')
-rw-r--r--src/libstd/rt/backtrace.rs4
-rw-r--r--src/libstd/rt/mod.rs84
2 files changed, 82 insertions, 6 deletions
diff --git a/src/libstd/rt/backtrace.rs b/src/libstd/rt/backtrace.rs
index 11257d506b0..107518ef27c 100644
--- a/src/libstd/rt/backtrace.rs
+++ b/src/libstd/rt/backtrace.rs
@@ -238,7 +238,7 @@ mod imp {
     use mem;
     use option::{Some, None, Option};
     use result::{Ok, Err};
-    use rt::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT};
+    use rustrt::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT};
 
     /// As always - iOS on arm uses SjLj exceptions and
     /// _Unwind_Backtrace is even not available there. Still,
@@ -667,7 +667,7 @@ mod imp {
     use option::{Some, None};
     use path::Path;
     use result::{Ok, Err};
-    use rt::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT};
+    use rustrt::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT};
     use slice::SlicePrelude;
     use str::StrPrelude;
     use dynamic_lib::DynamicLibrary;
diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs
index b97e80d0dc1..21b4edb6375 100644
--- a/src/libstd/rt/mod.rs
+++ b/src/libstd/rt/mod.rs
@@ -54,8 +54,11 @@ Several modules in `core` are clients of `rt`:
 // FIXME: this should not be here.
 #![allow(missing_docs)]
 
+#![allow(dead_code)]
+
 use failure;
 use rustrt;
+use os;
 
 // Reexport some of our utilities which are expected by other crates.
 pub use self::util::{default_sched_threads, min_stack, running_on_valgrind};
@@ -63,9 +66,7 @@ pub use self::util::{default_sched_threads, min_stack, running_on_valgrind};
 // Reexport functionality from librustrt and other crates underneath the
 // standard library which work together to create the entire runtime.
 pub use alloc::heap;
-pub use rustrt::{task, local, mutex, exclusive, stack, args, rtio, thread};
-pub use rustrt::{Stdio, Stdout, Stderr, begin_unwind, begin_unwind_fmt};
-pub use rustrt::{bookkeeping, at_exit, unwind, DEFAULT_ERROR_CODE, Runtime};
+pub use rustrt::{begin_unwind, begin_unwind_fmt, at_exit};
 
 // Simple backtrace functionality (to print on panic)
 pub mod backtrace;
@@ -81,7 +82,82 @@ mod util;
 #[allow(experimental)]
 pub fn init(argc: int, argv: *const *const u8) {
     rustrt::init(argc, argv);
-    unsafe { unwind::register(failure::on_fail); }
+    unsafe { rustrt::unwind::register(failure::on_fail); }
+}
+
+#[cfg(any(windows, android))]
+static OS_DEFAULT_STACK_ESTIMATE: uint = 1 << 20;
+#[cfg(all(unix, not(android)))]
+static OS_DEFAULT_STACK_ESTIMATE: uint = 2 * (1 << 20);
+
+#[cfg(not(test))]
+#[lang = "start"]
+fn lang_start(main: *const u8, argc: int, argv: *const *const u8) -> int {
+    use mem;
+    start(argc, argv, proc() {
+        let main: extern "Rust" fn() = unsafe { mem::transmute(main) };
+        main();
+    })
+}
+
+/// Executes the given procedure after initializing the runtime with the given
+/// argc/argv.
+///
+/// This procedure is guaranteed to run on the thread calling this function, but
+/// the stack bounds for this rust task will *not* be set. Care must be taken
+/// for this function to not overflow its stack.
+///
+/// This function will only return once *all* native threads in the system have
+/// exited.
+pub fn start(argc: int, argv: *const *const u8, main: proc()) -> int {
+    use prelude::*;
+    use rt;
+    use rustrt::task::Task;
+    use str;
+
+    let something_around_the_top_of_the_stack = 1;
+    let addr = &something_around_the_top_of_the_stack as *const int;
+    let my_stack_top = addr as uint;
+
+    // FIXME #11359 we just assume that this thread has a stack of a
+    // certain size, and estimate that there's at most 20KB of stack
+    // frames above our current position.
+    let my_stack_bottom = my_stack_top + 20000 - OS_DEFAULT_STACK_ESTIMATE;
+
+    // When using libgreen, one of the first things that we do is to turn off
+    // the SIGPIPE signal (set it to ignore). By default, some platforms will
+    // send a *signal* when a EPIPE error would otherwise be delivered. This
+    // runtime doesn't install a SIGPIPE handler, causing it to kill the
+    // program, which isn't exactly what we want!
+    //
+    // Hence, we set SIGPIPE to ignore when the program starts up in order to
+    // prevent this problem.
+    #[cfg(windows)] fn ignore_sigpipe() {}
+    #[cfg(unix)] fn ignore_sigpipe() {
+        use libc;
+        use libc::funcs::posix01::signal::signal;
+        unsafe {
+            assert!(signal(libc::SIGPIPE, libc::SIG_IGN) != -1);
+        }
+    }
+    ignore_sigpipe();
+
+    init(argc, argv);
+    let mut exit_code = None;
+    let mut main = Some(main);
+    let mut task = box Task::new(Some((my_stack_bottom, my_stack_top)),
+                                 Some(rustrt::thread::main_guard_page()));
+    task.name = Some(str::Slice("<main>"));
+    drop(task.run(|| {
+        unsafe {
+            rustrt::stack::record_os_managed_stack_bounds(my_stack_bottom, my_stack_top);
+        }
+        (main.take().unwrap())();
+        exit_code = Some(os::get_exit_status());
+    }).destroy());
+    unsafe { rt::cleanup(); }
+    // If the exit code wasn't set, then the task block must have panicked.
+    return exit_code.unwrap_or(rustrt::DEFAULT_ERROR_CODE);
 }
 
 /// One-time runtime cleanup.