about summary refs log tree commit diff
path: root/src/libgreen/sched.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/libgreen/sched.rs')
-rw-r--r--src/libgreen/sched.rs130
1 files changed, 69 insertions, 61 deletions
diff --git a/src/libgreen/sched.rs b/src/libgreen/sched.rs
index c323dbb92d7..301198a0676 100644
--- a/src/libgreen/sched.rs
+++ b/src/libgreen/sched.rs
@@ -46,10 +46,10 @@ pub struct Scheduler {
     /// inside this pool of schedulers
     pub task_state: TaskState,
     /// There are N work queues, one per scheduler.
-    work_queue: deque::Worker<~GreenTask>,
+    work_queue: deque::Worker<Box<GreenTask>>,
     /// Work queues for the other schedulers. These are created by
     /// cloning the core work queues.
-    work_queues: Vec<deque::Stealer<~GreenTask>>,
+    work_queues: Vec<deque::Stealer<Box<GreenTask>>>,
     /// The queue of incoming messages from other schedulers.
     /// These are enqueued by SchedHandles after which a remote callback
     /// is triggered to handle the message.
@@ -71,7 +71,7 @@ pub struct Scheduler {
     no_sleep: bool,
     /// The scheduler runs on a special task. When it is not running
     /// it is stored here instead of the work queue.
-    sched_task: Option<~GreenTask>,
+    sched_task: Option<Box<GreenTask>>,
     /// An action performed after a context switch on behalf of the
     /// code running before the context switch
     cleanup_job: Option<CleanupJob>,
@@ -83,7 +83,7 @@ pub struct Scheduler {
     /// A fast XorShift rng for scheduler use
     rng: XorShiftRng,
     /// A togglable idle callback
-    idle_callback: Option<~PausableIdleCallback:Send>,
+    idle_callback: Option<Box<PausableIdleCallback:Send>>,
     /// A countdown that starts at a random value and is decremented
     /// every time a yield check is performed. When it hits 0 a task
     /// will yield.
@@ -100,7 +100,7 @@ pub struct Scheduler {
     //      destroyed before it's actually destroyed.
 
     /// The event loop used to drive the scheduler and perform I/O
-    pub event_loop: ~EventLoop:Send,
+    pub event_loop: Box<EventLoop:Send>,
 }
 
 /// An indication of how hard to work on a given operation, the difference
@@ -123,9 +123,9 @@ impl Scheduler {
     // * Initialization Functions
 
     pub fn new(pool_id: uint,
-               event_loop: ~EventLoop:Send,
-               work_queue: deque::Worker<~GreenTask>,
-               work_queues: Vec<deque::Stealer<~GreenTask>>,
+               event_loop: Box<EventLoop:Send>,
+               work_queue: deque::Worker<Box<GreenTask>>,
+               work_queues: Vec<deque::Stealer<Box<GreenTask>>>,
                sleeper_list: SleeperList,
                state: TaskState)
         -> Scheduler {
@@ -136,9 +136,9 @@ impl Scheduler {
     }
 
     pub fn new_special(pool_id: uint,
-                       event_loop: ~EventLoop:Send,
-                       work_queue: deque::Worker<~GreenTask>,
-                       work_queues: Vec<deque::Stealer<~GreenTask>>,
+                       event_loop: Box<EventLoop:Send>,
+                       work_queue: deque::Worker<Box<GreenTask>>,
+                       work_queues: Vec<deque::Stealer<Box<GreenTask>>>,
                        sleeper_list: SleeperList,
                        run_anything: bool,
                        friend: Option<SchedHandle>,
@@ -183,7 +183,7 @@ impl Scheduler {
     pub fn bootstrap(mut ~self) {
 
         // Build an Idle callback.
-        let cb = box SchedRunner as ~Callback:Send;
+        let cb = box SchedRunner as Box<Callback:Send>;
         self.idle_callback = Some(self.event_loop.pausable_idle_callback(cb));
 
         // Create a task for the scheduler with an empty context.
@@ -224,14 +224,14 @@ impl Scheduler {
 
     // This does not return a scheduler, as the scheduler is placed
     // inside the task.
-    pub fn run(mut ~self, stask: ~GreenTask) -> ~GreenTask {
+    pub fn run(mut ~self, stask: Box<GreenTask>) -> Box<GreenTask> {
 
         // This is unsafe because we need to place the scheduler, with
         // the event_loop inside, inside our task. But we still need a
         // mutable reference to the event_loop to give it the "run"
         // command.
         unsafe {
-            let event_loop: *mut ~EventLoop:Send = &mut self.event_loop;
+            let event_loop: *mut Box<EventLoop:Send> = &mut self.event_loop;
             // Our scheduler must be in the task before the event loop
             // is started.
             stask.put_with_sched(self);
@@ -271,7 +271,7 @@ impl Scheduler {
     // If we try really hard to do some work, but no work is available to be
     // done, then we fall back to epoll() to block this thread waiting for more
     // work (instead of busy waiting).
-    fn run_sched_once(mut ~self, stask: ~GreenTask) {
+    fn run_sched_once(mut ~self, stask: Box<GreenTask>) {
         // Make sure that we're not lying in that the `stask` argument is indeed
         // the scheduler task for this scheduler.
         assert!(self.sched_task.is_none());
@@ -349,9 +349,9 @@ impl Scheduler {
     // returns the still-available scheduler. At this point all
     // message-handling will count as a turn of work, and as a result
     // return None.
-    fn interpret_message_queue(mut ~self, stask: ~GreenTask,
+    fn interpret_message_queue(mut ~self, stask: Box<GreenTask>,
                                effort: EffortLevel)
-            -> (~Scheduler, ~GreenTask, bool)
+            -> (Box<Scheduler>, Box<GreenTask>, bool)
     {
 
         let msg = if effort == DontTryTooHard {
@@ -432,8 +432,8 @@ impl Scheduler {
         }
     }
 
-    fn do_work(mut ~self,
-               stask: ~GreenTask) -> (~Scheduler, ~GreenTask, bool) {
+    fn do_work(mut ~self, stask: Box<GreenTask>)
+               -> (Box<Scheduler>, Box<GreenTask>, bool) {
         rtdebug!("scheduler calling do work");
         match self.find_work() {
             Some(task) => {
@@ -459,7 +459,7 @@ impl Scheduler {
     // First step in the process is to find a task. This function does
     // that by first checking the local queue, and if there is no work
     // there, trying to steal from the remote work queues.
-    fn find_work(&mut self) -> Option<~GreenTask> {
+    fn find_work(&mut self) -> Option<Box<GreenTask>> {
         rtdebug!("scheduler looking for work");
         if !self.steal_for_yield {
             match self.work_queue.pop() {
@@ -497,7 +497,7 @@ impl Scheduler {
     // Try stealing from all queues the scheduler knows about. This
     // naive implementation can steal from our own queue or from other
     // special schedulers.
-    fn try_steals(&mut self) -> Option<~GreenTask> {
+    fn try_steals(&mut self) -> Option<Box<GreenTask>> {
         let work_queues = &mut self.work_queues;
         let len = work_queues.len();
         let start_index = self.rng.gen_range(0, len);
@@ -517,9 +517,11 @@ impl Scheduler {
     // * Task Routing Functions - Make sure tasks send up in the right
     // place.
 
-    fn process_task(mut ~self, cur: ~GreenTask,
-                    mut next: ~GreenTask,
-                    schedule_fn: SchedulingFn) -> (~Scheduler, ~GreenTask) {
+    fn process_task(mut ~self,
+                    cur: Box<GreenTask>,
+                    mut next: Box<GreenTask>,
+                    schedule_fn: SchedulingFn)
+                    -> (Box<Scheduler>, Box<GreenTask>) {
         rtdebug!("processing a task");
 
         match next.take_unwrap_home() {
@@ -549,7 +551,7 @@ impl Scheduler {
         }
     }
 
-    fn send_task_home(task: ~GreenTask) {
+    fn send_task_home(task: Box<GreenTask>) {
         let mut task = task;
         match task.take_unwrap_home() {
             HomeSched(mut home_handle) => home_handle.send(PinnedTask(task)),
@@ -559,7 +561,7 @@ impl Scheduler {
 
     /// Take a non-homed task we aren't allowed to run here and send
     /// it to the designated friend scheduler to execute.
-    fn send_to_friend(&mut self, task: ~GreenTask) {
+    fn send_to_friend(&mut self, task: Box<GreenTask>) {
         rtdebug!("sending a task to friend");
         match self.friend_handle {
             Some(ref mut handle) => {
@@ -576,7 +578,7 @@ impl Scheduler {
     /// Pushes the task onto the work stealing queue and tells the
     /// event loop to run it later. Always use this instead of pushing
     /// to the work queue directly.
-    pub fn enqueue_task(&mut self, task: ~GreenTask) {
+    pub fn enqueue_task(&mut self, task: Box<GreenTask>) {
 
         // We push the task onto our local queue clone.
         assert!(!task.is_sched());
@@ -609,9 +611,10 @@ impl Scheduler {
     // old task as inputs.
 
     pub fn change_task_context(mut ~self,
-                               current_task: ~GreenTask,
-                               mut next_task: ~GreenTask,
-                               f: |&mut Scheduler, ~GreenTask|) -> ~GreenTask {
+                               current_task: Box<GreenTask>,
+                               mut next_task: Box<GreenTask>,
+                               f: |&mut Scheduler, Box<GreenTask>|)
+                               -> Box<GreenTask> {
         let f_opaque = ClosureConverter::from_fn(f);
 
         let current_task_dupe = &*current_task as *GreenTask;
@@ -655,7 +658,7 @@ impl Scheduler {
         // When the context swaps back to this task we immediately
         // run the cleanup job, as expected by the previously called
         // swap_contexts function.
-        let mut current_task: ~GreenTask = unsafe {
+        let mut current_task: Box<GreenTask> = unsafe {
             cast::transmute(current_task_dupe)
         };
         current_task.sched.get_mut_ref().run_cleanup_job();
@@ -688,8 +691,10 @@ impl Scheduler {
 
     // * Context Swapping Helpers - Here be ugliness!
 
-    pub fn resume_task_immediately(~self, cur: ~GreenTask,
-                                   next: ~GreenTask) -> (~Scheduler, ~GreenTask) {
+    pub fn resume_task_immediately(~self,
+                                   cur: Box<GreenTask>,
+                                   next: Box<GreenTask>)
+                                   -> (Box<Scheduler>, Box<GreenTask>) {
         assert!(cur.is_sched());
         let mut cur = self.change_task_context(cur, next, |sched, stask| {
             assert!(sched.sched_task.is_none());
@@ -698,9 +703,10 @@ impl Scheduler {
         (cur.sched.take_unwrap(), cur)
     }
 
-    fn resume_task_immediately_cl(sched: ~Scheduler,
-                                  cur: ~GreenTask,
-                                  next: ~GreenTask) -> (~Scheduler, ~GreenTask) {
+    fn resume_task_immediately_cl(sched: Box<Scheduler>,
+                                  cur: Box<GreenTask>,
+                                  next: Box<GreenTask>)
+                                  -> (Box<Scheduler>, Box<GreenTask>) {
         sched.resume_task_immediately(cur, next)
     }
 
@@ -726,7 +732,7 @@ impl Scheduler {
     /// guaranteed that this function will not return before the given closure
     /// has returned.
     pub fn deschedule_running_task_and_then(mut ~self,
-                                            cur: ~GreenTask,
+                                            cur: Box<GreenTask>,
                                             f: |&mut Scheduler, BlockedTask|) {
         // Trickier - we need to get the scheduler task out of self
         // and use it as the destination.
@@ -736,8 +742,8 @@ impl Scheduler {
     }
 
     pub fn switch_running_tasks_and_then(~self,
-                                         cur: ~GreenTask,
-                                         next: ~GreenTask,
+                                         cur: Box<GreenTask>,
+                                         next: Box<GreenTask>,
                                          f: |&mut Scheduler, BlockedTask|) {
         // And here comes one of the sad moments in which a lock is used in a
         // core portion of the rust runtime. As always, this is highly
@@ -768,8 +774,10 @@ impl Scheduler {
         cur.put();
     }
 
-    fn switch_task(sched: ~Scheduler, cur: ~GreenTask,
-                   next: ~GreenTask) -> (~Scheduler, ~GreenTask) {
+    fn switch_task(sched: Box<Scheduler>,
+                   cur: Box<GreenTask>,
+                   next: Box<GreenTask>)
+                   -> (Box<Scheduler>, Box<GreenTask>) {
         let mut cur = sched.change_task_context(cur, next, |sched, last_task| {
             if last_task.is_sched() {
                 assert!(sched.sched_task.is_none());
@@ -785,7 +793,7 @@ impl Scheduler {
 
     /// Called by a running task to end execution, after which it will
     /// be recycled by the scheduler for reuse in a new task.
-    pub fn terminate_current_task(mut ~self, cur: ~GreenTask) -> ! {
+    pub fn terminate_current_task(mut ~self, cur: Box<GreenTask>) -> ! {
         // Similar to deschedule running task and then, but cannot go through
         // the task-blocking path. The task is already dying.
         let stask = self.sched_task.take_unwrap();
@@ -797,13 +805,13 @@ impl Scheduler {
         fail!("should never return!");
     }
 
-    pub fn run_task(~self, cur: ~GreenTask, next: ~GreenTask) {
+    pub fn run_task(~self, cur: Box<GreenTask>, next: Box<GreenTask>) {
         let (sched, task) =
             self.process_task(cur, next, Scheduler::switch_task);
         task.put_with_sched(sched);
     }
 
-    pub fn run_task_later(mut cur: ~GreenTask, next: ~GreenTask) {
+    pub fn run_task_later(mut cur: Box<GreenTask>, next: Box<GreenTask>) {
         let mut sched = cur.sched.take_unwrap();
         sched.enqueue_task(next);
         cur.put_with_sched(sched);
@@ -813,7 +821,7 @@ impl Scheduler {
     /// to introduce some amount of randomness to the scheduler. Currently the
     /// randomness is a result of performing a round of work stealing (which
     /// may end up stealing from the current scheduler).
-    pub fn yield_now(mut ~self, cur: ~GreenTask) {
+    pub fn yield_now(mut ~self, cur: Box<GreenTask>) {
         // Async handles trigger the scheduler by calling yield_now on the local
         // task, which eventually gets us to here. See comments in SchedRunner
         // for more info on this.
@@ -832,7 +840,7 @@ impl Scheduler {
         }
     }
 
-    pub fn maybe_yield(mut ~self, cur: ~GreenTask) {
+    pub fn maybe_yield(mut ~self, cur: Box<GreenTask>) {
         // It's possible for sched tasks to possibly call this function, and it
         // just means that they're likely sending on channels (which
         // occasionally call this function). Sched tasks follow different paths
@@ -881,20 +889,20 @@ impl Scheduler {
 
 // Supporting types
 
-type SchedulingFn = fn (~Scheduler, ~GreenTask, ~GreenTask)
-                            -> (~Scheduler, ~GreenTask);
+type SchedulingFn = fn(Box<Scheduler>, Box<GreenTask>, Box<GreenTask>)
+                       -> (Box<Scheduler>, Box<GreenTask>);
 
 pub enum SchedMessage {
     Wake,
     Shutdown,
-    NewNeighbor(deque::Stealer<~GreenTask>),
-    PinnedTask(~GreenTask),
-    TaskFromFriend(~GreenTask),
-    RunOnce(~GreenTask),
+    NewNeighbor(deque::Stealer<Box<GreenTask>>),
+    PinnedTask(Box<GreenTask>),
+    TaskFromFriend(Box<GreenTask>),
+    RunOnce(Box<GreenTask>),
 }
 
 pub struct SchedHandle {
-    remote: ~RemoteCallback:Send,
+    remote: Box<RemoteCallback:Send>,
     queue: msgq::Producer<SchedMessage>,
     pub sched_id: uint
 }
@@ -920,18 +928,18 @@ impl Callback for SchedRunner {
         // This function could be converted to `GreenTask::convert` if
         // absolutely necessary, but for cleanliness it is much better to not
         // use the conversion function.
-        let task: ~Task = Local::take();
+        let task: Box<Task> = Local::take();
         task.yield_now();
     }
 }
 
 struct CleanupJob {
-    task: ~GreenTask,
+    task: Box<GreenTask>,
     f: UnsafeTaskReceiver
 }
 
 impl CleanupJob {
-    pub fn new(task: ~GreenTask, f: UnsafeTaskReceiver) -> CleanupJob {
+    pub fn new(task: Box<GreenTask>, f: UnsafeTaskReceiver) -> CleanupJob {
         CleanupJob {
             task: task,
             f: f
@@ -948,14 +956,14 @@ impl CleanupJob {
 // complaining
 type UnsafeTaskReceiver = raw::Closure;
 trait ClosureConverter {
-    fn from_fn(|&mut Scheduler, ~GreenTask|) -> Self;
-    fn to_fn(self) -> |&mut Scheduler, ~GreenTask|;
+    fn from_fn(|&mut Scheduler, Box<GreenTask>|) -> Self;
+    fn to_fn(self) -> |&mut Scheduler, Box<GreenTask>|;
 }
 impl ClosureConverter for UnsafeTaskReceiver {
-    fn from_fn(f: |&mut Scheduler, ~GreenTask|) -> UnsafeTaskReceiver {
+    fn from_fn(f: |&mut Scheduler, Box<GreenTask>|) -> UnsafeTaskReceiver {
         unsafe { cast::transmute(f) }
     }
-    fn to_fn(self) -> |&mut Scheduler, ~GreenTask| {
+    fn to_fn(self) -> |&mut Scheduler, Box<GreenTask>| {
         unsafe { cast::transmute(self) }
     }
 }
@@ -1218,7 +1226,7 @@ mod test {
             // Signal from the special task that we are done.
             let (tx, rx) = channel::<()>();
 
-            fn run(next: ~GreenTask) {
+            fn run(next: Box<GreenTask>) {
                 let mut task = GreenTask::convert(Local::take());
                 let sched = task.sched.take_unwrap();
                 sched.run_task(task, next)