about summary refs log tree commit diff
path: root/src/rt/rust_task.h
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2013-04-05 11:55:43 -0700
committerPatrick Walton <pcwalton@mimiga.net>2013-04-19 11:53:34 -0700
commitca8e99fd78ab9b56c5bdc61027b032ad52c2ec8b (patch)
treee3fef1f74bbfaa9ee6846c67941b9f2d8dab0b78 /src/rt/rust_task.h
parent2dbe20a5610c3244feab0db5ab20ff062dc91085 (diff)
downloadrust-ca8e99fd78ab9b56c5bdc61027b032ad52c2ec8b.tar.gz
rust-ca8e99fd78ab9b56c5bdc61027b032ad52c2ec8b.zip
rt: Fix scalability problem with big stacks on 32 bit
Diffstat (limited to 'src/rt/rust_task.h')
-rw-r--r--src/rt/rust_task.h14
1 files changed, 14 insertions, 0 deletions
diff --git a/src/rt/rust_task.h b/src/rt/rust_task.h
index 00d20fefc0e..e8b3ef44ac0 100644
--- a/src/rt/rust_task.h
+++ b/src/rt/rust_task.h
@@ -133,6 +133,9 @@
 #define RZ_BSD_32   (1024*20)
 #define RZ_BSD_64   (1024*20)
 
+// The threshold beyond which we switch to the C stack.
+#define STACK_THRESHOLD (1024 * 1024)
+
 #ifdef __linux__
 #ifdef __i386__
 #define RED_ZONE_SIZE RZ_LINUX_32
@@ -263,9 +266,13 @@ private:
     uintptr_t next_c_sp;
     uintptr_t next_rust_sp;
 
+    // The big stack.
+    stk_seg *big_stack;
+
     // Called when the atomic refcount reaches zero
     void delete_this();
 
+    bool new_big_stack();
     void new_stack_fast(size_t requested_sz);
     void new_stack(size_t requested_sz);
     void free_stack(stk_seg *stk);
@@ -284,6 +291,8 @@ private:
                        char const *file,
                        size_t line);
 
+    void dump_stacks();
+
     friend void task_start_wrapper(spawn_args *a);
     friend void cleanup_task(cleanup_args *a);
     friend void reset_stack_limit_on_c_stack(reset_args *a);
@@ -568,6 +577,11 @@ rust_task::new_stack_fast(size_t requested_sz) {
     // The minimum stack size, in bytes, of a Rust stack, excluding red zone
     size_t min_sz = sched_loop->min_stack_size;
 
+    if (requested_sz > STACK_THRESHOLD) {
+        if (new_big_stack())
+            return;
+    }
+
     // Try to reuse an existing stack segment
     if (stk != NULL && stk->next != NULL) {
         size_t next_sz = user_stack_size(stk->next);