Skip to content

Commit 4256d24

Browse files
committed
Percolate the (Scheduler, GreenTask) pair upwards
This is in preparation for running do_work in a loop while there are no active I/O handles. This changes the do_work and interpret_message_queue methods to return a triple where the last element is a boolean flag as to whether work was done or not. This commit preserves the same behavior as before, it simply re-structures the code in preparation for future work.
1 parent cc34dbb commit 4256d24

File tree

1 file changed

+56
-50
lines changed

1 file changed

+56
-50
lines changed

src/libgreen/sched.rs

Lines changed: 56 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -269,26 +269,26 @@ impl Scheduler {
269269

270270
// First we check for scheduler messages, these are higher
271271
// priority than regular tasks.
272-
let (sched, stask) =
273-
match self.interpret_message_queue(stask, DontTryTooHard) {
274-
Some(pair) => pair,
275-
None => return
276-
};
272+
let (sched, stask, did_work) =
273+
self.interpret_message_queue(stask, DontTryTooHard);
274+
if did_work {
275+
return stask.put_with_sched(sched);
276+
}
277277

278278
// This helper will use a randomized work-stealing algorithm
279279
// to find work.
280-
let (sched, stask) = match sched.do_work(stask) {
281-
Some(pair) => pair,
282-
None => return
283-
};
280+
let (sched, stask, did_work) = sched.do_work(stask);
281+
if did_work {
282+
return stask.put_with_sched(sched);
283+
}
284284

285285
// Now, before sleeping we need to find out if there really
286286
// were any messages. Give it your best!
287-
let (mut sched, stask) =
288-
match sched.interpret_message_queue(stask, GiveItYourBest) {
289-
Some(pair) => pair,
290-
None => return
291-
};
287+
let (mut sched, stask, did_work) =
288+
sched.interpret_message_queue(stask, GiveItYourBest);
289+
if did_work {
290+
return stask.put_with_sched(sched);
291+
}
292292

293293
// If we got here then there was no work to do.
294294
// Generate a SchedHandle and push it to the sleeper list so
@@ -318,7 +318,7 @@ impl Scheduler {
318318
// return None.
319319
fn interpret_message_queue(mut ~self, stask: ~GreenTask,
320320
effort: EffortLevel)
321-
-> Option<(~Scheduler, ~GreenTask)>
321+
-> (~Scheduler, ~GreenTask, bool)
322322
{
323323

324324
let msg = if effort == DontTryTooHard {
@@ -349,25 +349,25 @@ impl Scheduler {
349349
Some(PinnedTask(task)) => {
350350
let mut task = task;
351351
task.give_home(HomeSched(self.make_handle()));
352-
self.resume_task_immediately(stask, task).put();
353-
return None;
352+
let (sched, task) = self.resume_task_immediately(stask, task);
353+
(sched, task, true)
354354
}
355355
Some(TaskFromFriend(task)) => {
356356
rtdebug!("got a task from a friend. lovely!");
357-
self.process_task(stask, task,
358-
Scheduler::resume_task_immediately_cl);
359-
return None;
357+
let (sched, task) =
358+
self.process_task(stask, task,
359+
Scheduler::resume_task_immediately_cl);
360+
(sched, task, true)
360361
}
361362
Some(RunOnce(task)) => {
362363
// bypass the process_task logic to force running this task once
363364
// on this home scheduler. This is often used for I/O (homing).
364-
self.resume_task_immediately(stask, task).put();
365-
return None;
365+
let (sched, task) = self.resume_task_immediately(stask, task);
366+
(sched, task, true)
366367
}
367368
Some(Wake) => {
368369
self.sleepy = false;
369-
stask.put_with_sched(self);
370-
return None;
370+
(self, stask, true)
371371
}
372372
Some(Shutdown) => {
373373
rtdebug!("shutting down");
@@ -389,31 +389,30 @@ impl Scheduler {
389389
// event loop references we will shut down.
390390
self.no_sleep = true;
391391
self.sleepy = false;
392-
stask.put_with_sched(self);
393-
return None;
392+
(self, stask, true)
394393
}
395394
Some(NewNeighbor(neighbor)) => {
396395
self.work_queues.push(neighbor);
397-
return Some((self, stask));
398-
}
399-
None => {
400-
return Some((self, stask));
396+
(self, stask, false)
401397
}
398+
None => (self, stask, false)
402399
}
403400
}
404401

405-
fn do_work(mut ~self, stask: ~GreenTask) -> Option<(~Scheduler, ~GreenTask)> {
402+
fn do_work(mut ~self,
403+
stask: ~GreenTask) -> (~Scheduler, ~GreenTask, bool) {
406404
rtdebug!("scheduler calling do work");
407405
match self.find_work() {
408406
Some(task) => {
409407
rtdebug!("found some work! running the task");
410-
self.process_task(stask, task,
411-
Scheduler::resume_task_immediately_cl);
412-
return None;
408+
let (sched, task) =
409+
self.process_task(stask, task,
410+
Scheduler::resume_task_immediately_cl);
411+
(sched, task, true)
413412
}
414413
None => {
415414
rtdebug!("no work was found, returning the scheduler struct");
416-
return Some((self, stask));
415+
(self, stask, false)
417416
}
418417
}
419418
}
@@ -486,7 +485,8 @@ impl Scheduler {
486485
// place.
487486

488487
fn process_task(mut ~self, cur: ~GreenTask,
489-
mut next: ~GreenTask, schedule_fn: SchedulingFn) {
488+
mut next: ~GreenTask,
489+
schedule_fn: SchedulingFn) -> (~Scheduler, ~GreenTask) {
490490
rtdebug!("processing a task");
491491

492492
match next.take_unwrap_home() {
@@ -495,23 +495,23 @@ impl Scheduler {
495495
rtdebug!("sending task home");
496496
next.give_home(HomeSched(home_handle));
497497
Scheduler::send_task_home(next);
498-
cur.put_with_sched(self);
498+
(self, cur)
499499
} else {
500500
rtdebug!("running task here");
501501
next.give_home(HomeSched(home_handle));
502-
schedule_fn(self, cur, next);
502+
schedule_fn(self, cur, next)
503503
}
504504
}
505505
AnySched if self.run_anything => {
506506
rtdebug!("running anysched task here");
507507
next.give_home(AnySched);
508-
schedule_fn(self, cur, next);
508+
schedule_fn(self, cur, next)
509509
}
510510
AnySched => {
511511
rtdebug!("sending task to friend");
512512
next.give_home(AnySched);
513513
self.send_to_friend(next);
514-
cur.put_with_sched(self);
514+
(self, cur)
515515
}
516516
}
517517
}
@@ -664,18 +664,19 @@ impl Scheduler {
664664
// * Context Swapping Helpers - Here be ugliness!
665665

666666
pub fn resume_task_immediately(~self, cur: ~GreenTask,
667-
next: ~GreenTask) -> ~GreenTask {
667+
next: ~GreenTask) -> (~Scheduler, ~GreenTask) {
668668
assert!(cur.is_sched());
669-
self.change_task_context(cur, next, |sched, stask| {
669+
let mut cur = self.change_task_context(cur, next, |sched, stask| {
670670
assert!(sched.sched_task.is_none());
671671
sched.sched_task = Some(stask);
672-
})
672+
});
673+
(cur.sched.take_unwrap(), cur)
673674
}
674675

675676
fn resume_task_immediately_cl(sched: ~Scheduler,
676677
cur: ~GreenTask,
677-
next: ~GreenTask) {
678-
sched.resume_task_immediately(cur, next).put()
678+
next: ~GreenTask) -> (~Scheduler, ~GreenTask) {
679+
sched.resume_task_immediately(cur, next)
679680
}
680681

681682
/// Block a running task, context switch to the scheduler, then pass the
@@ -741,15 +742,17 @@ impl Scheduler {
741742
cur.put();
742743
}
743744

744-
fn switch_task(sched: ~Scheduler, cur: ~GreenTask, next: ~GreenTask) {
745-
sched.change_task_context(cur, next, |sched, last_task| {
745+
fn switch_task(sched: ~Scheduler, cur: ~GreenTask,
746+
next: ~GreenTask) -> (~Scheduler, ~GreenTask) {
747+
let mut cur = sched.change_task_context(cur, next, |sched, last_task| {
746748
if last_task.is_sched() {
747749
assert!(sched.sched_task.is_none());
748750
sched.sched_task = Some(last_task);
749751
} else {
750752
sched.enqueue_task(last_task);
751753
}
752-
}).put()
754+
});
755+
(cur.sched.take_unwrap(), cur)
753756
}
754757

755758
// * Task Context Helpers
@@ -769,7 +772,9 @@ impl Scheduler {
769772
}
770773

771774
pub fn run_task(~self, cur: ~GreenTask, next: ~GreenTask) {
772-
self.process_task(cur, next, Scheduler::switch_task);
775+
let (sched, task) =
776+
self.process_task(cur, next, Scheduler::switch_task);
777+
task.put_with_sched(sched);
773778
}
774779

775780
pub fn run_task_later(mut cur: ~GreenTask, next: ~GreenTask) {
@@ -836,7 +841,8 @@ impl Scheduler {
836841

837842
// Supporting types
838843

839-
type SchedulingFn = extern "Rust" fn (~Scheduler, ~GreenTask, ~GreenTask);
844+
type SchedulingFn = fn (~Scheduler, ~GreenTask, ~GreenTask)
845+
-> (~Scheduler, ~GreenTask);
840846

841847
pub enum SchedMessage {
842848
Wake,

0 commit comments

Comments
 (0)