diff options
| author | Brian Anderson <banderson@mozilla.com> | 2013-07-31 23:12:20 -0700 |
|---|---|---|
| committer | Brian Anderson <banderson@mozilla.com> | 2013-08-09 16:45:50 -0700 |
| commit | b75915d0ca20c6d066a7368ad53491a55a5a57d2 (patch) | |
| tree | d4f4a08c262940345b2cd5a1a223772f6aefb985 /src/libstd/task | |
| parent | d39255616004ea43dfabcf33b20ed2a80cd31dff (diff) | |
| download | rust-b75915d0ca20c6d066a7368ad53491a55a5a57d2.tar.gz rust-b75915d0ca20c6d066a7368ad53491a55a5a57d2.zip | |
Remove the C++ runtime. Sayonara
Diffstat (limited to 'src/libstd/task')
| -rw-r--r-- | src/libstd/task/local_data_priv.rs | 36 | ||||
| -rw-r--r-- | src/libstd/task/mod.rs | 110 | ||||
| -rw-r--r-- | src/libstd/task/rt.rs | 66 | ||||
| -rw-r--r-- | src/libstd/task/spawn.rs | 143 |
4 files changed, 48 insertions, 307 deletions
diff --git a/src/libstd/task/local_data_priv.rs b/src/libstd/task/local_data_priv.rs index 95d3cbaf89b..3a11dee3138 100644 --- a/src/libstd/task/local_data_priv.rs +++ b/src/libstd/task/local_data_priv.rs @@ -15,32 +15,21 @@ use libc; use local_data; use prelude::*; use ptr; -use task::rt; use unstable::raw; use util; -use super::rt::rust_task; use rt::task::{Task, LocalStorage}; pub enum Handle { - OldHandle(*rust_task), NewHandle(*mut LocalStorage) } impl Handle { pub fn new() -> Handle { - use rt::{context, OldTaskContext}; use rt::local::Local; unsafe { - match context() { - OldTaskContext => { - OldHandle(rt::rust_get_task()) - } - _ => { - let task = Local::unsafe_borrow::<Task>(); - NewHandle(&mut (*task).storage) - } - } + let task = Local::unsafe_borrow::<Task>(); + NewHandle(&mut (*task).storage) } } } @@ -109,26 +98,6 @@ fn cleanup_task_local_map(map_ptr: *libc::c_void) { // Gets the map from the runtime. Lazily initialises if not done so already. unsafe fn get_local_map(handle: Handle) -> &mut TaskLocalMap { - unsafe fn oldsched_map(task: *rust_task) -> &mut TaskLocalMap { - extern fn cleanup_extern_cb(map_ptr: *libc::c_void) { - cleanup_task_local_map(map_ptr); - } - - // Relies on the runtime initialising the pointer to null. - // Note: the map is an owned pointer and is "owned" by TLS. It is moved - // into the tls slot for this task, and then mutable loans are taken - // from this slot to modify the map. - let map_ptr = rt::rust_get_task_local_data(task); - if (*map_ptr).is_null() { - // First time TLS is used, create a new map and set up the necessary - // TLS information for its safe destruction - let map: TaskLocalMap = ~[]; - *map_ptr = cast::transmute(map); - rt::rust_task_local_data_atexit(task, cleanup_extern_cb); - } - return cast::transmute(map_ptr); - } - unsafe fn newsched_map(local: *mut LocalStorage) -> &mut TaskLocalMap { // This is based on the same idea as the oldsched code above. match &mut *local { @@ -152,7 +121,6 @@ unsafe fn get_local_map(handle: Handle) -> &mut TaskLocalMap { } match handle { - OldHandle(task) => oldsched_map(task), NewHandle(local_storage) => newsched_map(local_storage) } } diff --git a/src/libstd/task/mod.rs b/src/libstd/task/mod.rs index 269c828a984..09431c05e22 100644 --- a/src/libstd/task/mod.rs +++ b/src/libstd/task/mod.rs @@ -42,7 +42,7 @@ use cmp::Eq; use comm::{stream, Chan, GenericChan, GenericPort, Port}; use result::Result; use result; -use rt::{context, OldTaskContext, in_green_task_context}; +use rt::in_green_task_context; use rt::local::Local; use unstable::finally::Finally; use util; @@ -54,7 +54,6 @@ use util; #[cfg(test)] use task; mod local_data_priv; -pub mod rt; pub mod spawn; /** @@ -535,35 +534,21 @@ pub fn with_task_name<U>(blk: &fn(Option<&str>) -> U) -> U { } } } else { - fail!("no task name exists in %?", context()) + fail!("no task name exists in non-green task context") } } pub fn yield() { //! Yield control to the task scheduler - use rt::{context, OldTaskContext}; use rt::local::Local; use rt::sched::Scheduler; - unsafe { - match context() { - OldTaskContext => { - let task_ = rt::rust_get_task(); - let killed = rt::rust_task_yield(task_); - if killed && !failing() { - fail!("killed"); - } - } - _ => { - // XXX: What does yield really mean in newsched? - // FIXME(#7544): Optimize this, since we know we won't block. - let sched = Local::take::<Scheduler>(); - do sched.deschedule_running_task_and_then |sched, task| { - sched.enqueue_blocked_task(task); - } - } - } + // XXX: What does yield really mean in newsched? + // FIXME(#7544): Optimize this, since we know we won't block. + let sched = Local::take::<Scheduler>(); + do sched.deschedule_running_task_and_then |sched, task| { + sched.enqueue_blocked_task(task); } } @@ -572,17 +557,8 @@ pub fn failing() -> bool { use rt::task::Task; - match context() { - OldTaskContext => { - unsafe { - rt::rust_task_is_unwinding(rt::rust_get_task()) - } - } - _ => { - do Local::borrow::<Task, bool> |local| { - local.unwinder.unwinding - } - } + do Local::borrow::<Task, bool> |local| { + local.unwinder.unwinding } } @@ -605,29 +581,19 @@ pub fn unkillable<U>(f: &fn() -> U) -> U { use rt::task::Task; unsafe { - match context() { - OldTaskContext => { - let t = rt::rust_get_task(); - do (|| { - rt::rust_task_inhibit_kill(t); - f() - }).finally { - rt::rust_task_allow_kill(t); - } - } - _ if in_green_task_context() => { - // The inhibits/allows might fail and need to borrow the task. - let t = Local::unsafe_borrow::<Task>(); - do (|| { - (*t).death.inhibit_kill((*t).unwinder.unwinding); - f() - }).finally { - (*t).death.allow_kill((*t).unwinder.unwinding); - } + if in_green_task_context() { + // The inhibits/allows might fail and need to borrow the task. + let t = Local::unsafe_borrow::<Task>(); + do (|| { + (*t).death.inhibit_kill((*t).unwinder.unwinding); + f() + }).finally { + (*t).death.allow_kill((*t).unwinder.unwinding); } + } else { // FIXME(#3095): This should be an rtabort as soon as the scheduler // no longer uses a workqueue implemented with an Exclusive. - _ => f() + f() } } } @@ -636,27 +602,17 @@ pub fn unkillable<U>(f: &fn() -> U) -> U { pub unsafe fn rekillable<U>(f: &fn() -> U) -> U { use rt::task::Task; - match context() { - OldTaskContext => { - let t = rt::rust_get_task(); - do (|| { - rt::rust_task_allow_kill(t); - f() - }).finally { - rt::rust_task_inhibit_kill(t); - } - } - _ if in_green_task_context() => { - let t = Local::unsafe_borrow::<Task>(); - do (|| { - (*t).death.allow_kill((*t).unwinder.unwinding); - f() - }).finally { - (*t).death.inhibit_kill((*t).unwinder.unwinding); - } + if in_green_task_context() { + let t = Local::unsafe_borrow::<Task>(); + do (|| { + (*t).death.allow_kill((*t).unwinder.unwinding); + f() + }).finally { + (*t).death.inhibit_kill((*t).unwinder.unwinding); } + } else { // FIXME(#3095): As in unkillable(). - _ => f() + f() } } @@ -1034,14 +990,8 @@ fn test_try_fail() { #[cfg(test)] fn get_sched_id() -> int { - if context() == OldTaskContext { - unsafe { - rt::rust_get_sched_id() as int - } - } else { - do Local::borrow::<::rt::sched::Scheduler, int> |sched| { - sched.sched_id() as int - } + do Local::borrow::<::rt::sched::Scheduler, int> |sched| { + sched.sched_id() as int } } diff --git a/src/libstd/task/rt.rs b/src/libstd/task/rt.rs deleted file mode 100644 index 13c51230dc2..00000000000 --- a/src/libstd/task/rt.rs +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright 2012 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. - -/*! - -The task interface to the runtime - -*/ - -#[doc(hidden)]; - -use libc; - -#[allow(non_camel_case_types)] // runtime type -pub type sched_id = int; -#[allow(non_camel_case_types)] // runtime type -pub type task_id = int; - -// These are both opaque runtime/compiler types that we don't know the -// structure of and should only deal with via unsafe pointer -#[allow(non_camel_case_types)] // runtime type -pub type rust_task = libc::c_void; -#[allow(non_camel_case_types)] // runtime type -pub type rust_closure = libc::c_void; - -extern { - #[rust_stack] - pub fn rust_task_yield(task: *rust_task) -> bool; - - pub fn rust_get_sched_id() -> sched_id; - pub fn rust_new_sched(num_threads: libc::uintptr_t) -> sched_id; - - pub fn get_task_id() -> task_id; - #[rust_stack] - pub fn rust_get_task() -> *rust_task; - - pub fn new_task() -> *rust_task; - pub fn rust_new_task_in_sched(id: sched_id) -> *rust_task; - - pub fn start_task(task: *rust_task, closure: *rust_closure); - - pub fn rust_task_is_unwinding(task: *rust_task) -> bool; - pub fn rust_osmain_sched_id() -> sched_id; - #[rust_stack] - pub fn rust_task_inhibit_kill(t: *rust_task); - #[rust_stack] - pub fn rust_task_allow_kill(t: *rust_task); - #[rust_stack] - pub fn rust_task_inhibit_yield(t: *rust_task); - #[rust_stack] - pub fn rust_task_allow_yield(t: *rust_task); - pub fn rust_task_kill_other(task: *rust_task); - pub fn rust_task_kill_all(task: *rust_task); - - #[rust_stack] - pub fn rust_get_task_local_data(task: *rust_task) -> *mut *libc::c_void; - #[rust_stack] - pub fn rust_task_local_data_atexit(task: *rust_task, cleanup_fn: *u8); -} diff --git a/src/libstd/task/spawn.rs b/src/libstd/task/spawn.rs index 314377b8dc9..1a38dfc3d88 100644 --- a/src/libstd/task/spawn.rs +++ b/src/libstd/task/spawn.rs @@ -81,9 +81,6 @@ use container::MutableMap; use comm::{Chan, GenericChan, oneshot}; use hashmap::{HashSet, HashSetConsumeIterator}; use local_data; -use task::local_data_priv::{local_get, local_set, OldHandle}; -use task::rt::rust_task; -use task::rt; use task::{Failure, SingleThreaded}; use task::{Success, TaskOpts, TaskResult}; use task::unkillable; @@ -91,7 +88,7 @@ use to_bytes::IterBytes; use uint; use util; use unstable::sync::Exclusive; -use rt::{OldTaskContext, NewRtContext, context, in_green_task_context}; +use rt::in_green_task_context; use rt::local::Local; use rt::task::{Task, Sched}; use rt::kill::KillHandle; @@ -107,14 +104,12 @@ use rt::work_queue::WorkQueue; // Transitionary. #[deriving(Eq)] enum TaskHandle { - OldTask(*rust_task), NewTask(KillHandle), } impl Clone for TaskHandle { fn clone(&self) -> TaskHandle { match *self { - OldTask(x) => OldTask(x), NewTask(ref x) => NewTask(x.clone()), } } @@ -123,7 +118,6 @@ impl Clone for TaskHandle { impl IterBytes for TaskHandle { fn iter_bytes(&self, lsb0: bool, f: &fn(buf: &[u8]) -> bool) -> bool { match *self { - OldTask(ref x) => x.iter_bytes(lsb0, f), NewTask(ref x) => x.iter_bytes(lsb0, f), } } @@ -498,7 +492,6 @@ struct RuntimeGlue; impl RuntimeGlue { unsafe fn kill_task(task: TaskHandle) { match task { - OldTask(ptr) => rt::rust_task_kill_other(ptr), NewTask(handle) => { let mut handle = handle; do handle.kill().map_move |killed_task| { @@ -513,7 +506,6 @@ impl RuntimeGlue { unsafe fn kill_all_tasks(task: &TaskHandle) { match *task { - OldTask(ptr) => rt::rust_task_kill_all(ptr), // FIXME(#7544): Remove the kill_all feature entirely once the // oldsched goes away. NewTask(ref _handle) => rtabort!("can't kill_all in newsched"), @@ -521,12 +513,8 @@ impl RuntimeGlue { } fn with_task_handle_and_failing(blk: &fn(TaskHandle, bool)) { - match context() { - OldTaskContext => unsafe { - let me = rt::rust_get_task(); - blk(OldTask(me), rt::rust_task_is_unwinding(me)) - }, - NewRtContext if in_green_task_context() => unsafe { + if in_green_task_context() { + unsafe { // Can't use safe borrow, because the taskgroup destructor needs to // access the scheduler again to send kill signals to other tasks. let me = Local::unsafe_borrow::<Task>(); @@ -534,36 +522,15 @@ impl RuntimeGlue { // Will probably have to wait until the old rt is gone. blk(NewTask((*me).death.kill_handle.get_ref().clone()), (*me).unwinder.unwinding) - }, - NewRtContext => rtabort!("task dying in bad context"), + } + } else { + rtabort!("task dying in bad context") } } fn with_my_taskgroup<U>(blk: &fn(&Taskgroup) -> U) -> U { - match context() { - OldTaskContext => unsafe { - let me = rt::rust_get_task(); - do local_get(OldHandle(me), taskgroup_key()) |g| { - match g { - None => { - // Main task, doing first spawn ever. Lazily initialise here. - let mut members = TaskSet::new(); - members.insert(OldTask(me)); - let tasks = Exclusive::new(Some(TaskGroupData { - members: members, - descendants: TaskSet::new(), - })); - // Main task/group has no ancestors, no notifier, etc. - let group = @@mut Taskgroup(tasks, AncestorList(None), - true, None); - local_set(OldHandle(me), taskgroup_key(), group); - blk(&**group) - } - Some(&group) => blk(&**group) - } - } - }, - NewRtContext if in_green_task_context() => unsafe { + if in_green_task_context() { + unsafe { // Can't use safe borrow, because creating new hashmaps for the // tasksets requires an rng, which needs to borrow the sched. let me = Local::unsafe_borrow::<Task>(); @@ -587,8 +554,9 @@ impl RuntimeGlue { } Some(ref group) => group, }) - }, - NewRtContext => rtabort!("spawning in bad context"), + } + } else { + rtabort!("spawning in bad context") } } } @@ -598,7 +566,7 @@ fn gen_child_taskgroup(linked: bool, supervised: bool) -> Option<(TaskGroupArc, AncestorList, bool)> { // FIXME(#7544): Not safe to lazily initialize in the old runtime. Remove // this context check once 'spawn_raw_oldsched' is gone. - if context() == OldTaskContext || linked || supervised { + if linked || supervised { // with_my_taskgroup will lazily initialize the parent's taskgroup if // it doesn't yet exist. We don't want to call it in the unlinked case. do RuntimeGlue::with_my_taskgroup |spawner_group| { @@ -665,10 +633,10 @@ fn enlist_many(child: TaskHandle, child_arc: &TaskGroupArc, } pub fn spawn_raw(opts: TaskOpts, f: ~fn()) { - match context() { - OldTaskContext => spawn_raw_oldsched(opts, f), - _ if in_green_task_context() => spawn_raw_newsched(opts, f), - _ => fail!("can't spawn from this context") + if in_green_task_context() { + spawn_raw_newsched(opts, f) + } else { + fail!("can't spawn from this context") } } @@ -810,85 +778,6 @@ fn spawn_raw_newsched(mut opts: TaskOpts, f: ~fn()) { } -fn spawn_raw_oldsched(mut opts: TaskOpts, f: ~fn()) { - - let (child_tg, ancestors, is_main) = - gen_child_taskgroup(opts.linked, opts.supervised).expect("old runtime needs TG"); - - unsafe { - let child_data = Cell::new((child_tg, ancestors, f)); - // Being killed with the unsafe task/closure pointers would leak them. - do unkillable { - let (child_tg, ancestors, f) = child_data.take(); // :( - // Create child task. - let new_task = match opts.sched.mode { - DefaultScheduler => rt::new_task(), - _ => new_task_in_sched() - }; - assert!(!new_task.is_null()); - // Getting killed after here would leak the task. - let child_wrapper = make_child_wrapper(new_task, child_tg, - ancestors, is_main, opts.notify_chan.take(), f); - - let closure = cast::transmute(&child_wrapper); - - // Getting killed between these two calls would free the child's - // closure. (Reordering them wouldn't help - then getting killed - // between them would leak.) - rt::start_task(new_task, closure); - cast::forget(child_wrapper); - } - } - - // This function returns a closure-wrapper that we pass to the child task. - // (1) It sets up the notification channel. - // (2) It attempts to enlist in the child's group and all ancestor groups. - // (3a) If any of those fails, it leaves all groups, and does nothing. - // (3b) Otherwise it builds a task control structure and puts it in TLS, - // (4) ...and runs the provided body function. - fn make_child_wrapper(child: *rust_task, child_arc: TaskGroupArc, - ancestors: AncestorList, is_main: bool, - notify_chan: Option<Chan<TaskResult>>, - f: ~fn()) - -> ~fn() { - let child_data = Cell::new((notify_chan, child_arc, ancestors)); - let result: ~fn() = || { - let (notify_chan, child_arc, ancestors) = child_data.take(); // :( - let mut ancestors = ancestors; - // Child task runs this code. - - // Even if the below code fails to kick the child off, we must - // send Something on the notify channel. - - let notifier = notify_chan.map_move(|c| AutoNotify(c)); - - if enlist_many(OldTask(child), &child_arc, &mut ancestors) { - let group = @@mut Taskgroup(child_arc, ancestors, is_main, notifier); - unsafe { - local_set(OldHandle(child), taskgroup_key(), group); - } - - // Run the child's body. - f(); - - // TLS cleanup code will exit the taskgroup. - } - - // Run the box annihilator. - // FIXME #4428: Crashy. - // unsafe { cleanup::annihilate(); } - }; - return result; - } - - fn new_task_in_sched() -> *rust_task { - unsafe { - let sched_id = rt::rust_new_sched(1); - rt::rust_new_task_in_sched(sched_id) - } - } -} - #[test] fn test_spawn_raw_simple() { let (po, ch) = stream(); |
