]> git.lizzy.rs Git - rust.git/commitdiff
wip
authorBrian Anderson <banderson@mozilla.com>
Sun, 18 Dec 2011 00:45:13 +0000 (16:45 -0800)
committerBrian Anderson <banderson@mozilla.com>
Wed, 21 Dec 2011 04:15:09 +0000 (20:15 -0800)
src/libcore/core.rs
src/rt/circular_buffer.h
src/rt/rust_task.cpp
src/rt/rust_task.h
src/test/bench/task-perf-one-million.rs [new file with mode: 0644]

index 48e7a5f64cab951dc61a22e4eca8f5b8bf445b45..22f5dda00d89594a638c70f814d5bb8ae7a7fe06 100644 (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
 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;
+    }
+}
index f06e700b2f8cc13c33b56171f78b806258ce1d73..ae08c0c607427cbc5791790fe210ac137f7fcaa4 100644 (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:
index 2e6c41a8e7954173763b8f1e8b561d8e4381d82d..8957078294283e0a3a284cfd279863dd9d312c96 100644 (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
index 21d20691ac61adca655655baa20260a683dd5430..ba116c5a7bcffea26adab8dd0f57438fe5bba65a 100644 (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();
 };
 
 //
diff --git a/src/test/bench/task-perf-one-million.rs b/src/test/bench/task-perf-one-million.rs
new file mode 100644 (file)
index 0000000..8430351
--- /dev/null
@@ -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);
+}
\ No newline at end of file