-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Introduce libgreen/libnative, the M:N and 1:1 scheduling libraries #10965
Conversation
cc me (i'm no expert in this area but I am fascinated/hypnotized by the design space here) |
Great work! Thanks
|
And yet still manage to have a negative diffstat. This is an exciting PR. I reviewed the first half of it and looked over the second half. I think Runtime basically makes sense. Moving forward, how do you see mixed-native-and-green programs working, and what interface can we expose to C to embed runtimed Rust code? |
Mixing the two runtimes will be done by linking to extern mod native;
extern mod green;
fn spawn_native() {
do native::task::spawn(TaskOpts::new()) {
// this is forced to be a 1:1 task (this is a new OS thread)
}
}
fn spawn_green_pool() {
let mut pool = green::SchedPool::new(green::SchedConfig::new());
do pool.spawn(TaskOpts::new()) {
// this is an M:N task running in the above pool
do spawn {
// this is also an M:N task running in the above pool
}
}
pool.shutdown();
} The interface that I want to expose to C hasn't quite been worked out just yet. The interface would look someting like: fn some_function_called_from_c() {
let t: ~Task = acquire_the_c_task();
let result: Result<~Task, ~Any> = t.run(|| { /* rust runtime activated, all services available (including unwinding) */ });
deal_with_result(result)
} The idea here is that C code interfacing with rust code requiring the runtime would need to pass around and manage a I don't have the C interface implemented just yet (I figured this pull request was large enough), but I plan on doing it soon after landing this. |
LGTM! Thanks. |
After this PR what is the solution for people using the old |
I was under the impression that the users of |
@brson, I have pushed with many updates to the end (all the old commits are just rebased versions of their former selves) |
Still not ready for merging yet though as I have no replacement for |
After rethinking, I believe that this is now ready for merging. I have removed the extern mod native;
extern mod green;
use std::task::TaskOpts;
#[start]
fn start(argc: int, argv: **u8) -> int {
do native::start(argc, argv) {
let mut pool = green::SchedPool::new(green::PoolConfig::new());
let (p, c) = Chan::new();
do pool.spawn(TaskOpts::new()) {
println!("green pool");
c.send(());
}
p.recv();
pool.shutdown();
}
} I found out that All that being said, this could use some help with documentation, but I'd like to sort out |
How does native::start set up the stack baundary? r=me |
Right now native::start isn't actually responsible for setting up the stack boundary (because it has no way of knowing it), but rather the stack boundary is set up in native::lang_start which spawns a new task (which knows about the stack boundary). I'll open an issue about this. |
This trait is used to abstract the differences between 1:1 and M:N scheduling and is the sole dispatch point for the differences between these two scheduling modes. This, and the following series of commits, is not intended to compile. Only after the entire transition is complete are programs expected to compile.
This module will be used to manage the OS-specific TLS registers used to specify the bounds of the current rust stack (useful in 1:1 and M:N)
This module contains many M:N specific concepts. This will no longer be available with libgreen, and most functions aren't really that necessary today anyway. New testing primitives will be introduced as they become available for 1:1 and M:N. A new io::test module is introduced with the new ip4/ip6 address helpers to continue usage in io tests.
For now, this moves the following modules to std::sync * UnsafeArc (also removed unwrap method) * mpsc_queue * spsc_queue * atomics * mpmc_bounded_queue * deque We may want to remove some of the queues, but for now this moves things out of std::rt into std::sync
It is not the case that all programs will always be able to acquire an instance of the LocalIo borrow, so this commit exposes this limitation by returning Option<LocalIo> from LocalIo::borrow(). At the same time, a helper method LocalIo::maybe_raise() has been added in order to encapsulate the functionality of raising on io_error if there is on local I/O available.
Printing is an incredibly useful debugging utility, and it's not much help if your debugging prints just trigger an obscure abort when you need them most. In order to handle this case, forcibly fall back to a libc::write implementation of printing whenever a local task is not available. Note that this is *not* a 1:1 fallback. All 1:1 rust tasks will still have a local Task that it can go through (and stdio will be created through the local IO factory), this is only a fallback for "no context" rust code (such as that setting up the context).
This commit fixes the logging function to be safely implemented, as well as forcibly requiring a task to be present to use logging macros. This is safely implemented by transferring ownership of the logger from the task to the local stack frame in order to perform the print. This means that if a logger does more logging while logging a new one will be initialized and then will get overwritten once the initial logging function returns. Without a scheme such as this, it is possible to unsafely alias two loggers by logging twice (unsafely borrows from the task twice).
This allows creation of different sched pools with different io factories. Namely, this will be used to test the basic I/O loop in the green crate. This can also be used to override the global default.
This measure is simply to allow programs to continue compiling as they once did. In the future, this needs a more robust solution to choose how to start with libgreen or libnative.
Note that this removes a number of run-pass tests which are exercising behavior of the old runtime. This functionality no longer exists and is thoroughly tested inside of libgreen and libnative. There isn't really the notion of "starting the runtime" any more. The major notion now is "bootstrapping the initial task".
There was a race in the code previously where schedulers would *immediately* shut down after spawning the main task (because the global task count would still be 0). This fixes the logic by blocking the sched pool task in receving on a port instead of spawning a task into the pool to receive on a port. The modifications necessary were to have a "simple task" running by the time the code is executing, but this is a simple enough thing to implement and I forsee this being necessary to have implemented in the future anyway.
The queue has an async handle which must be destroyed before the loop is destroyed, so use a little bit of an option dance to get around this requirement.
It doesn't actually and we can get better incremental build times for modifications to librustuv if libsyntax/librustc don't need to get rebuilt
This is a very real problem with cvars on normal systems, and all of channels will not work if spurious wakeups are accepted. This problem is just solved with a synchronized flag (accessed in the cvar's lock) to see whether a signal() actually happened or whether it's spurious.
The uv loop was being destroyed before the async handle was being destroyed, so closing the async handle was causing a use-after-free in the uv loop. This was fixed by moving destruction of the queue's async handle to an earlier location and then actually freeing it once the loop has been dropped.
This happened because the environment of a procedure was never deallocated.
The rmake tests should depend on the target libraries (for linking), not just the host libraries (for running). The host file dependencies are also correct now because HLIBRUSTC_DEFAULT doesn't actually exist.
This prevents usage of the win32 utf-16 helper functions from outside of libstd. Closes rust-lang#9053
The only user of this was the homing code in librustuv, and it just manually does the cast from a pointer to a uint now.
These functions are all unnecessary now, and they only have meaning in the M:N context. Removing these functions uncovered a bug in the librustuv timer bindings, but it was fairly easy to cover (and the test is already committed). These cannot be completely removed just yet due to their usage in the WaitQueue of extra::sync, and until the mutex in libextra is rewritten it will not be possible to remove the deferred sends for channels.
This test also had a race condition in using the cvar/lock, so I fixed that up as well. The race originated from one half trying to destroy the lock when another half was using it.
* vec::raw::to_ptr is gone * Pausible => Pausable * Removing @ * Calling the main task "<main>" * Removing unused imports * Removing unused mut * Bringing some libextra tests up to date * Allowing compiletest to work at stage0 * Fixing the bootstrap-from-c rmake tests * assert => rtassert in a few cases * printing to stderr instead of stdout in fail!()
This pull request extracts all scheduling functionality from libstd, moving it into its own separate crates. The new libnative and libgreen will be the new way in which 1:1 and M:N scheduling is implemented. The standard library still requires an interface to the runtime, however, (think of things like `std::comm` and `io::println`). The interface is now defined by the `Runtime` trait inside of `std::rt`. The booting process is now that libgreen defines the start lang-item and that's it. I want to extend this soon to have libnative also have a "start lang item" but also allow libgreen and libnative to be linked together in the same process. For now though, only libgreen can be used to start a program (unless you define the start lang item yourself). Again though, I want to change this soon, I just figured that this pull request is large enough as-is. This certainly wasn't a smooth transition, certain functionality has no equivalent in this new separation, and some functionality is now better enabled through this new system. I did my best to separate all of the commits by topic and keep things fairly bite-sized, although are indeed larger than others. As a note, this is currently rebased on top of my `std::comm` rewrite (or at least an old copy of it), but none of those commits need reviewing (that will all happen in another pull request).
After rust-lang#10965, which introduces no-context printing, this is no longer needed. Fixes rust-lang#11043
…endoo Make `--explain` subcommand return 1 for missing lints changelog: The `--explain` subcommand now exits with the 1 exit code for missing lints
This pull request extracts all scheduling functionality from libstd, moving it into its own separate crates. The new libnative and libgreen will be the new way in which 1:1 and M:N scheduling is implemented. The standard library still requires an interface to the runtime, however, (think of things like
std::comm
andio::println
). The interface is now defined by theRuntime
trait inside ofstd::rt
.The booting process is now that libgreen defines the start lang-item and that's it. I want to extend this soon to have libnative also have a "start lang item" but also allow libgreen and libnative to be linked together in the same process. For now though, only libgreen can be used to start a program (unless you define the start lang item yourself). Again though, I want to change this soon, I just figured that this pull request is large enough as-is.
This certainly wasn't a smooth transition, certain functionality has no equivalent in this new separation, and some functionality is now better enabled through this new system. I did my best to separate all of the commits by topic and keep things fairly bite-sized, although are indeed larger than others.
As a note, this is currently rebased on top of my
std::comm
rewrite (or at least an old copy of it), but none of those commits need reviewing (that will all happen in another pull request).