This commit is contained in:
Brian Anderson 2011-12-17 16:45:13 -08:00
parent 128621be97
commit aeadc6269e
5 changed files with 88 additions and 1 deletions

View file

@ -6,6 +6,7 @@
import option::{some, none};
import option = option::t;
export option, some, none;
export repeat;
// Export the log levels as global constants. Higher levels mean
// more-verbosity. Error is the bottom level, default logging level is
@ -15,3 +16,16 @@ const error : int = 0;
const warn : int = 1;
const info : int = 2;
const debug : int = 3;
/*
Function: repeat
Execute a function for a set number of times
*/
fn repeat(times: uint, f: block()) {
let i = 0u;
while i < times {
f();
i += 1u;
}
}

View file

@ -7,7 +7,7 @@
class
circular_buffer : public kernel_owned<circular_buffer> {
static const size_t INITIAL_CIRCULAR_BUFFER_SIZE_IN_UNITS = 8;
static const size_t INITIAL_CIRCULAR_BUFFER_SIZE_IN_UNITS = 1;
static const size_t MAX_CIRCULAR_BUFFER_SIZE = 1 << 24;
public:

View file

@ -404,6 +404,9 @@ rust_task::yield(size_t time_in_us, bool *killed) {
*killed = true;
}
// We're not going to need any extra stack for a while
clear_stack_cache();
yield_timer.reset_us(time_in_us);
// Return to the scheduler.
@ -746,6 +749,15 @@ rust_task::del_stack() {
record_stack_limit();
}
void
rust_task::clear_stack_cache() {
A(sched, stk != NULL, "Expected to have a stack");
if (stk->prev != NULL) {
free_stk(this, stk->prev);
stk->prev = NULL;
}
}
void
rust_task::record_stack_limit() {
// The function prolog compares the amount of stack needed to the end of

View file

@ -203,6 +203,7 @@ rust_task : public kernel_owned<rust_task>, rust_cond
void reset_stack_limit();
bool on_rust_stack();
void check_stack_canary();
void clear_stack_cache();
};
//

View file

@ -0,0 +1,60 @@
// xfail-test FIXME: Can't run under valgrind - too much RAM
// FIXME: This doesn't spawn close to a million tasks yet
tag msg {
ready(comm::chan<msg>);
start;
done(int);
}
fn calc(&&args: (int, comm::chan<msg>)) {
let (depth, parent_ch) = args;
let port = comm::port();
let children = depth > 0 ? 20u : 0u;
let child_chs = [];
let sum = 0;
repeat (children) {||
task::spawn((depth - 1, comm::chan(port)), calc);
}
repeat (children) {||
alt comm::recv(port) {
ready(child_ch) {
child_chs += [child_ch];
}
}
}
comm::send(parent_ch, ready(comm::chan(port)));
alt comm::recv(port) {
start. {
vec::iter (child_chs) { |child_ch|
comm::send(child_ch, start);
}
}
}
repeat (children) {||
alt comm::recv(port) {
done(child_sum) { sum += child_sum; }
}
}
comm::send(parent_ch, done(sum + 1));
}
fn main() {
let port = comm::port();
task::spawn((3, comm::chan(port)), calc);
alt comm::recv(port) {
ready(chan) {
comm::send(chan, start);
}
}
let sum = alt comm::recv(port) {
done(sum) { sum }
};
log #fmt("How many tasks? That's right, %d tasks.", sum);
}