core: Add a scheduler mode, osmain, to spawn onto the main scheduler
This commit is contained in:
@@ -88,6 +88,13 @@ enum sched_mode {
|
|||||||
thread_per_task,
|
thread_per_task,
|
||||||
#[doc = "Tasks are distributed among a fixed number of OS threads"]
|
#[doc = "Tasks are distributed among a fixed number of OS threads"]
|
||||||
manual_threads(uint),
|
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 = "
|
#[doc = "
|
||||||
@@ -107,7 +114,7 @@ Scheduler configuration options
|
|||||||
"]
|
"]
|
||||||
type sched_opts = {
|
type sched_opts = {
|
||||||
mode: sched_mode,
|
mode: sched_mode,
|
||||||
native_stack_size: option<uint>,
|
native_stack_size: option<uint>
|
||||||
};
|
};
|
||||||
|
|
||||||
#[doc = "
|
#[doc = "
|
||||||
@@ -525,9 +532,14 @@ fn spawn_raw(opts: task_opts, +f: fn~()) unsafe {
|
|||||||
}
|
}
|
||||||
threads
|
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)
|
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 rust_task_is_unwinding(rt: *rust_task) -> bool;
|
||||||
fn unsupervise();
|
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);
|
||||||
|
}
|
||||||
|
|||||||
@@ -646,6 +646,12 @@ rust_dbg_call(dbg_callback cb, void *data) {
|
|||||||
return cb(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:
|
// Local Variables:
|
||||||
// mode: C++
|
// mode: C++
|
||||||
|
|||||||
@@ -93,6 +93,8 @@ public:
|
|||||||
void release_port_id(rust_port_id tid);
|
void release_port_id(rust_port_id tid);
|
||||||
|
|
||||||
void set_exit_status(int code);
|
void set_exit_status(int code);
|
||||||
|
|
||||||
|
rust_sched_id osmain_sched_id() { return osmain_scheduler; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* RUST_KERNEL_H */
|
#endif /* RUST_KERNEL_H */
|
||||||
|
|||||||
@@ -96,3 +96,4 @@ rust_dbg_lock_unlock
|
|||||||
rust_dbg_lock_wait
|
rust_dbg_lock_wait
|
||||||
rust_dbg_lock_signal
|
rust_dbg_lock_signal
|
||||||
rust_dbg_call
|
rust_dbg_call
|
||||||
|
rust_osmain_sched_id
|
||||||
|
|||||||
46
src/test/run-pass/osmain.rs
Normal file
46
src/test/run-pass/osmain.rs
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user