wip
This commit is contained in:
@@ -6,6 +6,7 @@
|
|||||||
import option::{some, none};
|
import option::{some, none};
|
||||||
import option = option::t;
|
import option = option::t;
|
||||||
export option, some, none;
|
export option, some, none;
|
||||||
|
export repeat;
|
||||||
|
|
||||||
// Export the log levels as global constants. Higher levels mean
|
// Export the log levels as global constants. Higher levels mean
|
||||||
// more-verbosity. Error is the bottom level, default logging level is
|
// more-verbosity. Error is the bottom level, default logging level is
|
||||||
@@ -15,3 +16,16 @@ const error : int = 0;
|
|||||||
const warn : int = 1;
|
const warn : int = 1;
|
||||||
const info : int = 2;
|
const info : int = 2;
|
||||||
const debug : int = 3;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
class
|
class
|
||||||
circular_buffer : public kernel_owned<circular_buffer> {
|
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;
|
static const size_t MAX_CIRCULAR_BUFFER_SIZE = 1 << 24;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -404,6 +404,9 @@ rust_task::yield(size_t time_in_us, bool *killed) {
|
|||||||
*killed = true;
|
*killed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We're not going to need any extra stack for a while
|
||||||
|
clear_stack_cache();
|
||||||
|
|
||||||
yield_timer.reset_us(time_in_us);
|
yield_timer.reset_us(time_in_us);
|
||||||
|
|
||||||
// Return to the scheduler.
|
// Return to the scheduler.
|
||||||
@@ -746,6 +749,15 @@ rust_task::del_stack() {
|
|||||||
record_stack_limit();
|
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
|
void
|
||||||
rust_task::record_stack_limit() {
|
rust_task::record_stack_limit() {
|
||||||
// The function prolog compares the amount of stack needed to the end of
|
// The function prolog compares the amount of stack needed to the end of
|
||||||
|
|||||||
@@ -203,6 +203,7 @@ rust_task : public kernel_owned<rust_task>, rust_cond
|
|||||||
void reset_stack_limit();
|
void reset_stack_limit();
|
||||||
bool on_rust_stack();
|
bool on_rust_stack();
|
||||||
void check_stack_canary();
|
void check_stack_canary();
|
||||||
|
void clear_stack_cache();
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|||||||
60
src/test/bench/task-perf-one-million.rs
Normal file
60
src/test/bench/task-perf-one-million.rs
Normal 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);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user