From aeadc6269ef76f4425a49d892ceac7ea311ef5c1 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sat, 17 Dec 2011 16:45:13 -0800 Subject: [PATCH] wip --- src/libcore/core.rs | 14 ++++++ src/rt/circular_buffer.h | 2 +- src/rt/rust_task.cpp | 12 +++++ src/rt/rust_task.h | 1 + src/test/bench/task-perf-one-million.rs | 60 +++++++++++++++++++++++++ 5 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 src/test/bench/task-perf-one-million.rs diff --git a/src/libcore/core.rs b/src/libcore/core.rs index 48e7a5f64cab..22f5dda00d89 100644 --- a/src/libcore/core.rs +++ b/src/libcore/core.rs @@ -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; + } +} diff --git a/src/rt/circular_buffer.h b/src/rt/circular_buffer.h index f06e700b2f8c..ae08c0c60742 100644 --- a/src/rt/circular_buffer.h +++ b/src/rt/circular_buffer.h @@ -7,7 +7,7 @@ class circular_buffer : public kernel_owned { - 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: diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp index 2e6c41a8e795..895707829428 100644 --- a/src/rt/rust_task.cpp +++ b/src/rt/rust_task.cpp @@ -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 diff --git a/src/rt/rust_task.h b/src/rt/rust_task.h index 21d20691ac61..ba116c5a7bcf 100644 --- a/src/rt/rust_task.h +++ b/src/rt/rust_task.h @@ -203,6 +203,7 @@ rust_task : public kernel_owned, rust_cond void reset_stack_limit(); bool on_rust_stack(); void check_stack_canary(); + void clear_stack_cache(); }; // diff --git a/src/test/bench/task-perf-one-million.rs b/src/test/bench/task-perf-one-million.rs new file mode 100644 index 000000000000..8430351b7e9a --- /dev/null +++ b/src/test/bench/task-perf-one-million.rs @@ -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); + start; + done(int); +} + +fn calc(&&args: (int, comm::chan)) { + 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); +} \ No newline at end of file