Skip to content
9 changes: 6 additions & 3 deletions doc/tutorial-tasks.md
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,8 @@ either task fails, it kills the other one.

~~~
# use std::task;
# fn sleep_forever() { loop { task::yield() } }
# use std::comm::oneshot;
# fn sleep_forever() { loop { let (p, c) = oneshot::<()>(); p.recv(); } }
# do task::try {
do spawn {
do spawn {
Expand All @@ -513,9 +514,10 @@ before returning. Hence:

~~~
# use std::comm::{stream, Chan, Port};
# use std::comm::oneshot;
# use std::task::{spawn, try};
# use std::task;
# fn sleep_forever() { loop { task::yield() } }
# fn sleep_forever() { loop { let (p, c) = oneshot::<()>(); p.recv(); } }
# do task::try {
let (receiver, sender): (Port<int>, Chan<int>) = stream();
do spawn { // Bidirectionally linked
Expand Down Expand Up @@ -543,7 +545,8 @@ an intermediate generation has already exited:

~~~
# use std::task;
# fn sleep_forever() { loop { task::yield() } }
# use std::comm::oneshot;
# fn sleep_forever() { loop { let (p, c) = oneshot::<()>(); p.recv(); } }
# fn wait_for_a_while() { do 1000.times { task::yield() } }
# do task::try::<int> {
do task::spawn_supervised {
Expand Down
10 changes: 9 additions & 1 deletion src/librustc/rustc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -299,10 +299,18 @@ bug and need to present an error.
*/
pub fn monitor(f: ~fn(diagnostic::Emitter)) {
use std::comm::*;

// XXX: This is a hack for newsched since it doesn't support split stacks.
// rustc needs a lot of stack!
static STACK_SIZE: uint = 4000000;

let (p, ch) = stream();
let ch = SharedChan::new(ch);
let ch_capture = ch.clone();
match do task::try || {
let mut task_builder = task::task();
task_builder.supervised();
task_builder.opts.stack_size = Some(STACK_SIZE);
match do task_builder.try {
let ch = ch_capture.clone();
let ch_capture = ch.clone();
// The 'diagnostics emitter'. Every error, warning, etc. should
Expand Down
1 change: 1 addition & 0 deletions src/librustpkg/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -998,6 +998,7 @@ fn test_rustpkg_test() {
}

#[test]
#[ignore(reason = "test not yet implemented")]
fn test_uninstall() {
let workspace = create_local_package(&PkgId::new("foo", &os::getcwd()));
let _output = command_line_test([~"info", ~"foo"], &workspace);
Expand Down
28 changes: 28 additions & 0 deletions src/libstd/rt/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,12 @@

//! Runtime environment settings

use from_str::FromStr;
use libc::{size_t, c_char, c_int};
use option::{Some, None};
use os;

// OLD RT stuff

pub struct Environment {
/// The number of threads to use by default
Expand Down Expand Up @@ -47,3 +52,26 @@ pub fn get() -> &Environment {
extern {
fn rust_get_rt_env() -> &Environment;
}

// NEW RT stuff

// Note that these are all accessed without any synchronization.
// They are expected to be initialized once then left alone.

static mut MIN_STACK: uint = 2000000;

pub fn init() {
unsafe {
match os::getenv("RUST_MIN_STACK") {
Some(s) => match FromStr::from_str(s) {
Some(i) => MIN_STACK = i,
None => ()
},
None => ()
}
}
}

pub fn min_stack() -> uint {
unsafe { MIN_STACK }
}
11 changes: 6 additions & 5 deletions src/libstd/rt/local.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ impl Local for IoFactoryObject {

#[cfg(test)]
mod test {
use option::None;
use unstable::run_in_bare_thread;
use rt::test::*;
use super::*;
Expand All @@ -137,7 +138,7 @@ mod test {
do run_in_bare_thread {
local_ptr::init_tls_key();
let mut sched = ~new_test_uv_sched();
let task = ~Task::new_root(&mut sched.stack_pool, || {});
let task = ~Task::new_root(&mut sched.stack_pool, None, || {});
Local::put(task);
let task: ~Task = Local::take();
cleanup_task(task);
Expand All @@ -149,11 +150,11 @@ mod test {
do run_in_bare_thread {
local_ptr::init_tls_key();
let mut sched = ~new_test_uv_sched();
let task = ~Task::new_root(&mut sched.stack_pool, || {});
let task = ~Task::new_root(&mut sched.stack_pool, None, || {});
Local::put(task);
let task: ~Task = Local::take();
cleanup_task(task);
let task = ~Task::new_root(&mut sched.stack_pool, || {});
let task = ~Task::new_root(&mut sched.stack_pool, None, || {});
Local::put(task);
let task: ~Task = Local::take();
cleanup_task(task);
Expand All @@ -166,7 +167,7 @@ mod test {
do run_in_bare_thread {
local_ptr::init_tls_key();
let mut sched = ~new_test_uv_sched();
let task = ~Task::new_root(&mut sched.stack_pool, || {});
let task = ~Task::new_root(&mut sched.stack_pool, None, || {});
Local::put(task);

unsafe {
Expand All @@ -182,7 +183,7 @@ mod test {
do run_in_bare_thread {
local_ptr::init_tls_key();
let mut sched = ~new_test_uv_sched();
let task = ~Task::new_root(&mut sched.stack_pool, || {});
let task = ~Task::new_root(&mut sched.stack_pool, None, || {});
Local::put(task);

let res = do Local::borrow::<Task,bool> |_task| {
Expand Down
8 changes: 4 additions & 4 deletions src/libstd/rt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ pub fn init(argc: int, argv: **u8, crate_map: *u8) {
// Need to propagate the unsafety to `start`.
unsafe {
args::init(argc, argv);
env::init();
logging::init(crate_map);
rust_update_gc_metadata(crate_map);
}
Expand Down Expand Up @@ -330,8 +331,7 @@ fn run_(main: ~fn(), use_main_sched: bool) -> int {
// In the case where we do not use a main_thread scheduler we
// run the main task in one of our threads.

let mut main_task = ~Task::new_root(&mut scheds[0].stack_pool,
main.take());
let mut main_task = ~Task::new_root(&mut scheds[0].stack_pool, None, main.take());
main_task.death.on_exit = Some(on_exit.take());
let main_task_cell = Cell::new(main_task);

Expand All @@ -351,7 +351,7 @@ fn run_(main: ~fn(), use_main_sched: bool) -> int {
let sched_cell = Cell::new(sched);
let thread = do Thread::start {
let mut sched = sched_cell.take();
let bootstrap_task = ~do Task::new_root(&mut sched.stack_pool) || {
let bootstrap_task = ~do Task::new_root(&mut sched.stack_pool, None) || {
rtdebug!("boostraping a non-primary scheduler");
};
sched.bootstrap(bootstrap_task);
Expand All @@ -368,7 +368,7 @@ fn run_(main: ~fn(), use_main_sched: bool) -> int {
let mut main_sched = main_sched.unwrap();

let home = Sched(main_sched.make_handle());
let mut main_task = ~Task::new_root_homed(&mut main_sched.stack_pool,
let mut main_task = ~Task::new_root_homed(&mut main_sched.stack_pool, None,
home, main.take());
main_task.death.on_exit = Some(on_exit.take());
rtdebug!("boostrapping main_task");
Expand Down
14 changes: 7 additions & 7 deletions src/libstd/rt/sched.rs
Original file line number Diff line number Diff line change
Expand Up @@ -833,7 +833,7 @@ mod test {
let mut sched = ~new_test_uv_sched();
let sched_handle = sched.make_handle();

let mut task = ~do Task::new_root_homed(&mut sched.stack_pool,
let mut task = ~do Task::new_root_homed(&mut sched.stack_pool, None,
Sched(sched_handle)) {
unsafe { *task_ran_ptr = true };
assert!(Task::on_appropriate_sched());
Expand Down Expand Up @@ -893,21 +893,21 @@ mod test {
// 3) task not homed, sched requeues
// 4) task not home, send home

let task1 = ~do Task::new_root_homed(&mut special_sched.stack_pool,
let task1 = ~do Task::new_root_homed(&mut special_sched.stack_pool, None,
Sched(t1_handle)) || {
rtassert!(Task::on_appropriate_sched());
};
rtdebug!("task1 id: **%u**", borrow::to_uint(task1));

let task2 = ~do Task::new_root(&mut normal_sched.stack_pool) {
let task2 = ~do Task::new_root(&mut normal_sched.stack_pool, None) {
rtassert!(Task::on_appropriate_sched());
};

let task3 = ~do Task::new_root(&mut normal_sched.stack_pool) {
let task3 = ~do Task::new_root(&mut normal_sched.stack_pool, None) {
rtassert!(Task::on_appropriate_sched());
};

let task4 = ~do Task::new_root_homed(&mut special_sched.stack_pool,
let task4 = ~do Task::new_root_homed(&mut special_sched.stack_pool, None,
Sched(t4_handle)) {
rtassert!(Task::on_appropriate_sched());
};
Expand All @@ -923,7 +923,7 @@ mod test {
let port = Cell::new(port);
let chan = Cell::new(chan);

let normal_task = ~do Task::new_root(&mut normal_sched.stack_pool) {
let normal_task = ~do Task::new_root(&mut normal_sched.stack_pool, None) {
rtdebug!("*about to submit task2*");
Scheduler::run_task(task2.take());
rtdebug!("*about to submit task4*");
Expand All @@ -938,7 +938,7 @@ mod test {

rtdebug!("normal task: %u", borrow::to_uint(normal_task));

let special_task = ~do Task::new_root(&mut special_sched.stack_pool) {
let special_task = ~do Task::new_root(&mut special_sched.stack_pool, None) {
rtdebug!("*about to submit task1*");
Scheduler::run_task(task1.take());
rtdebug!("*about to submit task3*");
Expand Down
41 changes: 25 additions & 16 deletions src/libstd/rt/task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use libc::{c_void, uintptr_t};
use ptr;
use prelude::*;
use option::{Option, Some, None};
use rt::env;
use rt::kill::Death;
use rt::local::Local;
use rt::logging::StdErrLogger;
Expand Down Expand Up @@ -85,38 +86,40 @@ impl Task {

// A helper to build a new task using the dynamically found
// scheduler and task. Only works in GreenTask context.
pub fn build_homed_child(f: ~fn(), home: SchedHome) -> ~Task {
pub fn build_homed_child(stack_size: Option<uint>, f: ~fn(), home: SchedHome) -> ~Task {
let f = Cell::new(f);
let home = Cell::new(home);
do Local::borrow::<Task, ~Task> |running_task| {
let mut sched = running_task.sched.take_unwrap();
let new_task = ~running_task.new_child_homed(&mut sched.stack_pool,
stack_size,
home.take(),
f.take());
running_task.sched = Some(sched);
new_task
}
}

pub fn build_child(f: ~fn()) -> ~Task {
Task::build_homed_child(f, AnySched)
pub fn build_child(stack_size: Option<uint>, f: ~fn()) -> ~Task {
Task::build_homed_child(stack_size, f, AnySched)
}

pub fn build_homed_root(f: ~fn(), home: SchedHome) -> ~Task {
pub fn build_homed_root(stack_size: Option<uint>, f: ~fn(), home: SchedHome) -> ~Task {
let f = Cell::new(f);
let home = Cell::new(home);
do Local::borrow::<Task, ~Task> |running_task| {
let mut sched = running_task.sched.take_unwrap();
let new_task = ~Task::new_root_homed(&mut sched.stack_pool,
home.take(),
f.take());
stack_size,
home.take(),
f.take());
running_task.sched = Some(sched);
new_task
}
}

pub fn build_root(f: ~fn()) -> ~Task {
Task::build_homed_root(f, AnySched)
pub fn build_root(stack_size: Option<uint>, f: ~fn()) -> ~Task {
Task::build_homed_root(stack_size, f, AnySched)
}

pub fn new_sched_task() -> Task {
Expand All @@ -137,17 +140,20 @@ impl Task {
}

pub fn new_root(stack_pool: &mut StackPool,
stack_size: Option<uint>,
start: ~fn()) -> Task {
Task::new_root_homed(stack_pool, AnySched, start)
Task::new_root_homed(stack_pool, stack_size, AnySched, start)
}

pub fn new_child(&mut self,
stack_pool: &mut StackPool,
stack_size: Option<uint>,
start: ~fn()) -> Task {
self.new_child_homed(stack_pool, AnySched, start)
self.new_child_homed(stack_pool, stack_size, AnySched, start)
}

pub fn new_root_homed(stack_pool: &mut StackPool,
stack_size: Option<uint>,
home: SchedHome,
start: ~fn()) -> Task {
Task {
Expand All @@ -160,14 +166,15 @@ impl Task {
death: Death::new(),
destroyed: false,
name: None,
coroutine: Some(Coroutine::new(stack_pool, start)),
coroutine: Some(Coroutine::new(stack_pool, stack_size, start)),
sched: None,
task_type: GreenTask(Some(~home))
}
}

pub fn new_child_homed(&mut self,
stack_pool: &mut StackPool,
stack_size: Option<uint>,
home: SchedHome,
start: ~fn()) -> Task {
Task {
Expand All @@ -181,7 +188,7 @@ impl Task {
death: self.death.new_child(),
destroyed: false,
name: None,
coroutine: Some(Coroutine::new(stack_pool, start)),
coroutine: Some(Coroutine::new(stack_pool, stack_size, start)),
sched: None,
task_type: GreenTask(Some(~home))
}
Expand Down Expand Up @@ -325,11 +332,13 @@ impl Drop for Task {

impl Coroutine {

pub fn new(stack_pool: &mut StackPool, start: ~fn()) -> Coroutine {
static MIN_STACK_SIZE: uint = 3000000; // XXX: Too much stack

pub fn new(stack_pool: &mut StackPool, stack_size: Option<uint>, start: ~fn()) -> Coroutine {
let stack_size = match stack_size {
Some(size) => size,
None => env::min_stack()
};
let start = Coroutine::build_start_wrapper(start);
let mut stack = stack_pool.take_segment(MIN_STACK_SIZE);
let mut stack = stack_pool.take_segment(stack_size);
let initial_context = Context::new(start, &mut stack);
Coroutine {
current_stack_segment: stack,
Expand Down
Loading