core: Add a scheduler mode, osmain, to spawn onto the main scheduler

This commit is contained in:
Brian Anderson
2012-04-03 14:03:27 -07:00
parent e1858882a4
commit bef72447e7
5 changed files with 90 additions and 2 deletions

View File

@@ -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);
}

View File

@@ -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++

View File

@@ -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 */

View File

@@ -96,3 +96,4 @@ rust_dbg_lock_unlock
rust_dbg_lock_wait
rust_dbg_lock_signal
rust_dbg_call
rust_osmain_sched_id

View File

@@ -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();
}
}