diff options
| author | Brian Anderson <banderson@mozilla.com> | 2012-04-03 14:03:27 -0700 |
|---|---|---|
| committer | Brian Anderson <banderson@mozilla.com> | 2012-04-03 14:28:30 -0700 |
| commit | bef72447e75b7e37f43d3a82ce40e419c7f747d2 (patch) | |
| tree | 92e5355f9320194ca9cb512b1079f73ca89de2c7 | |
| parent | e1858882a49bf0666d4ffb3f45989ac9dbe9c843 (diff) | |
| download | rust-bef72447e75b7e37f43d3a82ce40e419c7f747d2.tar.gz rust-bef72447e75b7e37f43d3a82ce40e419c7f747d2.zip | |
core: Add a scheduler mode, osmain, to spawn onto the main scheduler
| -rw-r--r-- | src/libcore/task.rs | 37 | ||||
| -rw-r--r-- | src/rt/rust_builtin.cpp | 6 | ||||
| -rw-r--r-- | src/rt/rust_kernel.h | 2 | ||||
| -rw-r--r-- | src/rt/rustrt.def.in | 1 | ||||
| -rw-r--r-- | src/test/run-pass/osmain.rs | 46 |
5 files changed, 90 insertions, 2 deletions
diff --git a/src/libcore/task.rs b/src/libcore/task.rs index dcd784fb2a3..cdf50aa4837 100644 --- a/src/libcore/task.rs +++ b/src/libcore/task.rs @@ -88,6 +88,13 @@ enum sched_mode { thread_per_task, #[doc = "Tasks are distributed among a fixed number of OS threads"] manual_threads(uint), + #[doc = " + Tasks are scheduled on the main OS thread + + The main OS thread is the thread used to launch the runtime which, + in most cases, is the process's initial thread as created by the OS. + "] + osmain } #[doc = " @@ -107,7 +114,7 @@ Scheduler configuration options "] type sched_opts = { mode: sched_mode, - native_stack_size: option<uint>, + native_stack_size: option<uint> }; #[doc = " @@ -525,9 +532,14 @@ fn spawn_raw(opts: task_opts, +f: fn~()) unsafe { } threads } + osmain { 0u /* Won't be used */ } }; - let sched_id = rustrt::rust_new_sched(num_threads); + let sched_id = if opts.mode != osmain { + rustrt::rust_new_sched(num_threads) + } else { + rustrt::rust_osmain_sched_id() + }; rustrt::rust_new_task_in_sched(sched_id) } @@ -553,6 +565,7 @@ native mod rustrt { fn rust_task_is_unwinding(rt: *rust_task) -> bool; fn unsupervise(); + fn rust_osmain_sched_id() -> sched_id; } @@ -897,3 +910,23 @@ fn test_avoid_copying_the_body_unsupervise() { } } } + +#[test] +fn test_osmain() { + let builder = task_builder(); + let opts = { + sched: some({ + mode: osmain, + native_stack_size: none + }) + with get_opts(builder) + }; + set_opts(builder, opts); + + let po = comm::port(); + let ch = comm::chan(po); + run(builder) {|| + comm::send(ch, ()); + } + comm::recv(po); +} diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index aa1f1ce1e6a..f13fd4a110b 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -646,6 +646,12 @@ rust_dbg_call(dbg_callback cb, void *data) { return cb(data); } +extern "C" CDECL rust_sched_id +rust_osmain_sched_id() { + rust_task *task = rust_sched_loop::get_task(); + return task->kernel->osmain_sched_id(); +} + // // Local Variables: // mode: C++ diff --git a/src/rt/rust_kernel.h b/src/rt/rust_kernel.h index 8c1d33c6a5e..927da963dad 100644 --- a/src/rt/rust_kernel.h +++ b/src/rt/rust_kernel.h @@ -93,6 +93,8 @@ public: void release_port_id(rust_port_id tid); void set_exit_status(int code); + + rust_sched_id osmain_sched_id() { return osmain_scheduler; } }; #endif /* RUST_KERNEL_H */ diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in index 0bc0fddaca7..c8219e922be 100644 --- a/src/rt/rustrt.def.in +++ b/src/rt/rustrt.def.in @@ -96,3 +96,4 @@ rust_dbg_lock_unlock rust_dbg_lock_wait rust_dbg_lock_signal rust_dbg_call +rust_osmain_sched_id diff --git a/src/test/run-pass/osmain.rs b/src/test/run-pass/osmain.rs new file mode 100644 index 00000000000..4112ee561f7 --- /dev/null +++ b/src/test/run-pass/osmain.rs @@ -0,0 +1,46 @@ +// Jump back and forth between the OS main thread and a new scheduler. +// The OS main scheduler should continue to be available and not terminate +// while it is not in use. + +fn main() { + run(10); +} + +fn run(i: int) { + + log(debug, i); + + if i == 0 { + ret; + } + + let builder = task::task_builder(); + let opts = { + sched: some({ + mode: task::osmain, + native_stack_size: none + }) + with task::get_opts(builder) + }; + task::set_opts(builder, opts); + task::unsupervise(builder); + task::run(builder) {|| + task::yield(); + let builder = task::task_builder(); + let opts = { + sched: some({ + mode: task::single_threaded, + native_stack_size: none + }) + with task::get_opts(builder) + }; + task::set_opts(builder, opts); + task::unsupervise(builder); + task::run(builder) {|| + task::yield(); + run(i - 1); + task::yield(); + } + task::yield(); + } +} |
