Skip to content

Commit bef7244

Browse files
committed
core: Add a scheduler mode, osmain, to spawn onto the main scheduler
1 parent e185888 commit bef7244

File tree

5 files changed

+90
-2
lines changed

5 files changed

+90
-2
lines changed

src/libcore/task.rs

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,13 @@ enum sched_mode {
8888
thread_per_task,
8989
#[doc = "Tasks are distributed among a fixed number of OS threads"]
9090
manual_threads(uint),
91+
#[doc = "
92+
Tasks are scheduled on the main OS thread
93+
94+
The main OS thread is the thread used to launch the runtime which,
95+
in most cases, is the process's initial thread as created by the OS.
96+
"]
97+
osmain
9198
}
9299

93100
#[doc = "
@@ -107,7 +114,7 @@ Scheduler configuration options
107114
"]
108115
type sched_opts = {
109116
mode: sched_mode,
110-
native_stack_size: option<uint>,
117+
native_stack_size: option<uint>
111118
};
112119

113120
#[doc = "
@@ -525,9 +532,14 @@ fn spawn_raw(opts: task_opts, +f: fn~()) unsafe {
525532
}
526533
threads
527534
}
535+
osmain { 0u /* Won't be used */ }
528536
};
529537

530-
let sched_id = rustrt::rust_new_sched(num_threads);
538+
let sched_id = if opts.mode != osmain {
539+
rustrt::rust_new_sched(num_threads)
540+
} else {
541+
rustrt::rust_osmain_sched_id()
542+
};
531543
rustrt::rust_new_task_in_sched(sched_id)
532544
}
533545

@@ -553,6 +565,7 @@ native mod rustrt {
553565

554566
fn rust_task_is_unwinding(rt: *rust_task) -> bool;
555567
fn unsupervise();
568+
fn rust_osmain_sched_id() -> sched_id;
556569
}
557570

558571

@@ -897,3 +910,23 @@ fn test_avoid_copying_the_body_unsupervise() {
897910
}
898911
}
899912
}
913+
914+
#[test]
915+
fn test_osmain() {
916+
let builder = task_builder();
917+
let opts = {
918+
sched: some({
919+
mode: osmain,
920+
native_stack_size: none
921+
})
922+
with get_opts(builder)
923+
};
924+
set_opts(builder, opts);
925+
926+
let po = comm::port();
927+
let ch = comm::chan(po);
928+
run(builder) {||
929+
comm::send(ch, ());
930+
}
931+
comm::recv(po);
932+
}

src/rt/rust_builtin.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,12 @@ rust_dbg_call(dbg_callback cb, void *data) {
646646
return cb(data);
647647
}
648648

649+
extern "C" CDECL rust_sched_id
650+
rust_osmain_sched_id() {
651+
rust_task *task = rust_sched_loop::get_task();
652+
return task->kernel->osmain_sched_id();
653+
}
654+
649655
//
650656
// Local Variables:
651657
// mode: C++

src/rt/rust_kernel.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ class rust_kernel {
9393
void release_port_id(rust_port_id tid);
9494

9595
void set_exit_status(int code);
96+
97+
rust_sched_id osmain_sched_id() { return osmain_scheduler; }
9698
};
9799

98100
#endif /* RUST_KERNEL_H */

src/rt/rustrt.def.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,3 +96,4 @@ rust_dbg_lock_unlock
9696
rust_dbg_lock_wait
9797
rust_dbg_lock_signal
9898
rust_dbg_call
99+
rust_osmain_sched_id

src/test/run-pass/osmain.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Jump back and forth between the OS main thread and a new scheduler.
2+
// The OS main scheduler should continue to be available and not terminate
3+
// while it is not in use.
4+
5+
fn main() {
6+
run(10);
7+
}
8+
9+
fn run(i: int) {
10+
11+
log(debug, i);
12+
13+
if i == 0 {
14+
ret;
15+
}
16+
17+
let builder = task::task_builder();
18+
let opts = {
19+
sched: some({
20+
mode: task::osmain,
21+
native_stack_size: none
22+
})
23+
with task::get_opts(builder)
24+
};
25+
task::set_opts(builder, opts);
26+
task::unsupervise(builder);
27+
task::run(builder) {||
28+
task::yield();
29+
let builder = task::task_builder();
30+
let opts = {
31+
sched: some({
32+
mode: task::single_threaded,
33+
native_stack_size: none
34+
})
35+
with task::get_opts(builder)
36+
};
37+
task::set_opts(builder, opts);
38+
task::unsupervise(builder);
39+
task::run(builder) {||
40+
task::yield();
41+
run(i - 1);
42+
task::yield();
43+
}
44+
task::yield();
45+
}
46+
}

0 commit comments

Comments
 (0)