diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2013-12-12 18:01:59 -0800 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2013-12-24 19:59:52 -0800 |
| commit | 51abdee5f1ad932671350fdd8a7911fe144d08b8 (patch) | |
| tree | e65726bf152c97cb9854a3e13b3818c0ecde5493 /src/libstd/rt/basic.rs | |
| parent | 6aadc9d18856f8e7ea8038e2c4b2ba0f9507e26a (diff) | |
| download | rust-51abdee5f1ad932671350fdd8a7911fe144d08b8.tar.gz rust-51abdee5f1ad932671350fdd8a7911fe144d08b8.zip | |
green: Rip the bandaid off, introduce libgreen
This extracts everything related to green scheduling from libstd and introduces a new libgreen crate. This mostly involves deleting most of std::rt and moving it to libgreen. Along with the movement of code, this commit rearchitects many functions in the scheduler in order to adapt to the fact that Local::take now *only* works on a Task, not a scheduler. This mostly just involved threading the current green task through in a few locations, but there were one or two spots where things got hairy. There are a few repercussions of this commit: * tube/rc have been removed (the runtime implementation of rc) * There is no longer a "single threaded" spawning mode for tasks. This is now encompassed by 1:1 scheduling + communication. Convenience methods have been introduced that are specific to libgreen to assist in the spawning of pools of schedulers.
Diffstat (limited to 'src/libstd/rt/basic.rs')
| -rw-r--r-- | src/libstd/rt/basic.rs | 230 |
1 files changed, 0 insertions, 230 deletions
diff --git a/src/libstd/rt/basic.rs b/src/libstd/rt/basic.rs deleted file mode 100644 index 3589582357c..00000000000 --- a/src/libstd/rt/basic.rs +++ /dev/null @@ -1,230 +0,0 @@ -// Copyright 2013 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! This is a basic event loop implementation not meant for any "real purposes" -//! other than testing the scheduler and proving that it's possible to have a -//! pluggable event loop. - -use prelude::*; - -use cast; -use rt::rtio::{EventLoop, IoFactory, RemoteCallback, PausableIdleCallback, - Callback}; -use unstable::sync::Exclusive; -use io::native; -use util; - -/// This is the only exported function from this module. -pub fn event_loop() -> ~EventLoop { - ~BasicLoop::new() as ~EventLoop -} - -struct BasicLoop { - work: ~[proc()], // pending work - idle: Option<*mut BasicPausable>, // only one is allowed - remotes: ~[(uint, ~Callback)], - next_remote: uint, - messages: Exclusive<~[Message]>, - io: ~IoFactory, -} - -enum Message { RunRemote(uint), RemoveRemote(uint) } - -impl BasicLoop { - fn new() -> BasicLoop { - BasicLoop { - work: ~[], - idle: None, - next_remote: 0, - remotes: ~[], - messages: Exclusive::new(~[]), - io: ~native::IoFactory as ~IoFactory, - } - } - - /// Process everything in the work queue (continually) - fn work(&mut self) { - while self.work.len() > 0 { - for work in util::replace(&mut self.work, ~[]).move_iter() { - work(); - } - } - } - - fn remote_work(&mut self) { - let messages = unsafe { - self.messages.with(|messages| { - if messages.len() > 0 { - Some(util::replace(messages, ~[])) - } else { - None - } - }) - }; - let messages = match messages { - Some(m) => m, None => return - }; - for message in messages.iter() { - self.message(*message); - } - } - - fn message(&mut self, message: Message) { - match message { - RunRemote(i) => { - match self.remotes.mut_iter().find(|& &(id, _)| id == i) { - Some(&(_, ref mut f)) => f.call(), - None => unreachable!() - } - } - RemoveRemote(i) => { - match self.remotes.iter().position(|&(id, _)| id == i) { - Some(i) => { self.remotes.remove(i); } - None => unreachable!() - } - } - } - } - - /// Run the idle callback if one is registered - fn idle(&mut self) { - unsafe { - match self.idle { - Some(idle) => { - if (*idle).active { - (*idle).work.call(); - } - } - None => {} - } - } - } - - fn has_idle(&self) -> bool { - unsafe { self.idle.is_some() && (**self.idle.get_ref()).active } - } -} - -impl EventLoop for BasicLoop { - fn run(&mut self) { - // Not exactly efficient, but it gets the job done. - while self.remotes.len() > 0 || self.work.len() > 0 || self.has_idle() { - - self.work(); - self.remote_work(); - - if self.has_idle() { - self.idle(); - continue - } - - unsafe { - // We block here if we have no messages to process and we may - // receive a message at a later date - self.messages.hold_and_wait(|messages| { - self.remotes.len() > 0 && - messages.len() == 0 && - self.work.len() == 0 - }) - } - } - } - - fn callback(&mut self, f: proc()) { - self.work.push(f); - } - - // XXX: Seems like a really weird requirement to have an event loop provide. - fn pausable_idle_callback(&mut self, cb: ~Callback) -> ~PausableIdleCallback { - let callback = ~BasicPausable::new(self, cb); - rtassert!(self.idle.is_none()); - unsafe { - let cb_ptr: &*mut BasicPausable = cast::transmute(&callback); - self.idle = Some(*cb_ptr); - } - return callback as ~PausableIdleCallback; - } - - fn remote_callback(&mut self, f: ~Callback) -> ~RemoteCallback { - let id = self.next_remote; - self.next_remote += 1; - self.remotes.push((id, f)); - ~BasicRemote::new(self.messages.clone(), id) as ~RemoteCallback - } - - fn io<'a>(&'a mut self) -> Option<&'a mut IoFactory> { - let factory: &mut IoFactory = self.io; - Some(factory) - } -} - -struct BasicRemote { - queue: Exclusive<~[Message]>, - id: uint, -} - -impl BasicRemote { - fn new(queue: Exclusive<~[Message]>, id: uint) -> BasicRemote { - BasicRemote { queue: queue, id: id } - } -} - -impl RemoteCallback for BasicRemote { - fn fire(&mut self) { - unsafe { - self.queue.hold_and_signal(|queue| { - queue.push(RunRemote(self.id)); - }) - } - } -} - -impl Drop for BasicRemote { - fn drop(&mut self) { - unsafe { - self.queue.hold_and_signal(|queue| { - queue.push(RemoveRemote(self.id)); - }) - } - } -} - -struct BasicPausable { - eloop: *mut BasicLoop, - work: ~Callback, - active: bool, -} - -impl BasicPausable { - fn new(eloop: &mut BasicLoop, cb: ~Callback) -> BasicPausable { - BasicPausable { - active: false, - work: cb, - eloop: eloop, - } - } -} - -impl PausableIdleCallback for BasicPausable { - fn pause(&mut self) { - self.active = false; - } - fn resume(&mut self) { - self.active = true; - } -} - -impl Drop for BasicPausable { - fn drop(&mut self) { - unsafe { - (*self.eloop).idle = None; - } - } -} |
