Skip to content

Commit 3f8095e

Browse files
committed
core::rt: Add a very basic multi-threaded scheduling test
1 parent 7f107c4 commit 3f8095e

File tree

1 file changed

+70
-2
lines changed

1 file changed

+70
-2
lines changed

src/libcore/rt/sched.rs

Lines changed: 70 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@ pub impl Scheduler {
114114
};
115115

116116
fn wake_up() {
117+
let sched = Local::take::<Scheduler>();
118+
sched.resume_task_from_queue();
117119
}
118120
}
119121

@@ -127,8 +129,8 @@ pub impl Scheduler {
127129
self.event_loop.callback(resume_task_from_queue);
128130

129131
fn resume_task_from_queue() {
130-
let scheduler = Local::take::<Scheduler>();
131-
scheduler.resume_task_from_queue();
132+
let sched = Local::take::<Scheduler>();
133+
sched.resume_task_from_queue();
132134
}
133135
}
134136

@@ -606,4 +608,70 @@ mod test {
606608
};
607609
}
608610
}
611+
612+
#[test]
613+
fn multithreading() {
614+
use clone::Clone;
615+
use iter::Times;
616+
use rt::work_queue::WorkQueue;
617+
use rt::comm::*;
618+
use container::Container;
619+
use vec::OwnedVector;
620+
use rt::rtio::RemoteCallback;
621+
622+
do run_in_bare_thread {
623+
let work_queue1 = WorkQueue::new();
624+
let work_queue2 = work_queue1.clone();
625+
626+
let loop1 = ~UvEventLoop::new();
627+
let mut sched1 = ~Scheduler::new(loop1, work_queue1.clone());
628+
let handle1 = sched1.make_handle();
629+
let sched1_cell = Cell(sched1);
630+
let handle1_cell = Cell(handle1);
631+
632+
let loop2 = ~UvEventLoop::new();
633+
let mut sched2 = ~Scheduler::new(loop2, work_queue2.clone());
634+
let handle2 = sched2.make_handle();
635+
let sched2_cell = Cell(sched2);
636+
let handle2_cell = Cell(handle2);
637+
638+
let _thread1 = do Thread::start {
639+
let mut sched1 = sched1_cell.take();
640+
sched1.run();
641+
};
642+
643+
let _thread2 = do Thread::start {
644+
let mut sched2 = sched2_cell.take();
645+
let handle1_cell = Cell(handle1_cell.take());
646+
let handle2_cell = Cell(handle2_cell.take());
647+
648+
let task = ~do Coroutine::new(&mut sched2.stack_pool) {
649+
// Hold handles to keep the schedulers alive
650+
let mut handle1 = handle1_cell.take();
651+
let mut handle2 = handle2_cell.take();
652+
653+
let mut ports = ~[];
654+
for 10.times {
655+
let (port, chan) = oneshot();
656+
let chan_cell = Cell(chan);
657+
do spawntask_later {
658+
chan_cell.take().send(());
659+
}
660+
ports.push(port);
661+
662+
// Make sure the other scheduler is awake
663+
handle1.remote.fire();
664+
handle2.remote.fire();
665+
}
666+
667+
while !ports.is_empty() {
668+
ports.pop().recv();
669+
}
670+
};
671+
672+
sched2.enqueue_task(task);
673+
sched2.run();
674+
};
675+
}
676+
}
609677
}

0 commit comments

Comments
 (0)