Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

79 lines (71 sloc) 2.958 kb
// 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.
/**
* Test performance of killing many tasks in a taskgroup.
* Along the way, tests various edge cases of ancestor group management.
* In particular, this tries to get each grandchild task to hit the
* "nobe_is_dead" case in each_ancestor only during task exit, but not during
* task spawn. This makes sure that defunct ancestor groups are handled correctly
* w.r.t. possibly leaving stale *rust_tasks lying around.
*/
// Creates in the background 'num_tasks' tasks, all blocked forever.
// Doesn't return until all such tasks are ready, but doesn't block forever itself.
fn grandchild_group(num_tasks: uint) {
let po = oldcomm::Port();
let ch = oldcomm::Chan(&po);
for num_tasks.times {
do task::spawn { // linked
oldcomm::send(ch, ());
oldcomm::recv(oldcomm::Port::<()>()); // block forever
}
}
error!("Grandchild group getting started");
for num_tasks.times {
// Make sure all above children are fully spawned; i.e., enlisted in
// their ancestor groups.
oldcomm::recv(po);
}
error!("Grandchild group ready to go.");
// Master grandchild task exits early.
}
fn spawn_supervised_blocking(myname: &str, +f: fn~()) {
let mut res = None;
task::task().future_result(|+r| res = Some(move r)).supervised().spawn(move f);
error!("%s group waiting", myname);
let x = option::unwrap(move res).recv();
assert x == task::Success;
}
fn main() {
let args = os::args();
let args = if os::getenv(~"RUST_BENCH").is_some() {
~[~"", ~"100000"]
} else if args.len() <= 1u {
~[~"", ~"100"]
} else {
copy args
};
let num_tasks = uint::from_str(args[1]).get();
// Main group #0 waits for unsupervised group #1.
// Grandparent group #1 waits for middle group #2, then fails, killing #3.
// Middle group #2 creates grandchild_group #3, waits for it to be ready, exits.
let x: result::Result<(),()> = do task::try { // unlinked
do spawn_supervised_blocking("grandparent") {
do spawn_supervised_blocking("middle") {
grandchild_group(num_tasks);
}
// When grandchild group is ready to go, make the middle group exit.
error!("Middle group wakes up and exits");
}
// Grandparent group waits for middle group to be gone, then fails
error!("Grandparent group wakes up and fails");
fail;
};
assert x.is_err();
}
Jump to Line
Something went wrong with that request. Please try again.