summary refs log tree commit diff
path: root/src/rt/rust_task_thread.cpp
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2012-02-09 01:13:32 -0800
committerBrian Anderson <banderson@mozilla.com>2012-02-09 19:00:16 -0800
commit79b1563abb32a385724bbe5ce6b4cdbee9ae5dc7 (patch)
treebaa648a32c783bc950299bc9d8e33201132366ee /src/rt/rust_task_thread.cpp
parentbfb80064d2dd37bd1e7009d98aa585253f5a2812 (diff)
downloadrust-79b1563abb32a385724bbe5ce6b4cdbee9ae5dc7.tar.gz
rust-79b1563abb32a385724bbe5ce6b4cdbee9ae5dc7.zip
rt: Use rust_task_thread's C-stack pool for native calls
Diffstat (limited to 'src/rt/rust_task_thread.cpp')
-rw-r--r--src/rt/rust_task_thread.cpp58
1 files changed, 45 insertions, 13 deletions
diff --git a/src/rt/rust_task_thread.cpp b/src/rt/rust_task_thread.cpp
index 4129969057c..48bd7f16bdf 100644
--- a/src/rt/rust_task_thread.cpp
+++ b/src/rt/rust_task_thread.cpp
@@ -61,10 +61,6 @@ rust_task_thread::~rust_task_thread() {
 #ifndef __WIN32__
     pthread_attr_destroy(&attr);
 #endif
-
-    if (cached_c_stack) {
-        destroy_stack(kernel, cached_c_stack);
-    }
 }
 
 void
@@ -72,7 +68,9 @@ rust_task_thread::activate(rust_task *task) {
     task->ctx.next = &c_context;
     DLOG(this, task, "descheduling...");
     lock.unlock();
+    prepare_c_stack();
     task->ctx.swap(c_context);
+    unprepare_c_stack();
     lock.lock();
     DLOG(this, task, "task has returned");
 }
@@ -287,6 +285,13 @@ rust_task_thread::start_main_loop() {
     DLOG(this, dom, "finished main-loop %d", id);
 
     lock.unlock();
+
+    I(this, !extra_c_stack);
+    if (cached_c_stack) {
+        unconfig_valgrind_stack(cached_c_stack);
+        destroy_stack(kernel, cached_c_stack);
+        cached_c_stack = NULL;
+    }
 }
 
 rust_crate_cache *
@@ -374,24 +379,51 @@ rust_task_thread::exit() {
     lock.signal();
 }
 
+// Before activating each task, make sure we have a C stack available.
+// It needs to be allocated ahead of time (while we're on our own
+// stack), because once we're on the Rust stack we won't have enough
+// room to do the allocation
+void
+rust_task_thread::prepare_c_stack() {
+    I(this, !extra_c_stack);
+    if (!cached_c_stack) {
+        cached_c_stack = create_stack(kernel, C_STACK_SIZE);
+    }
+}
+
+void
+rust_task_thread::unprepare_c_stack() {
+    if (extra_c_stack) {
+        destroy_stack(kernel, extra_c_stack);
+        extra_c_stack = NULL;
+    }
+}
+
+// NB: Runs on the Rust stack
 stk_seg *
 rust_task_thread::borrow_c_stack() {
-
-    if (cached_c_stack) {
-        stk_seg *your_stack = cached_c_stack;
-        cached_c_stack = NULL;
-        return your_stack;
+    I(this, cached_c_stack);
+    stk_seg *your_stack;
+    if (extra_c_stack) {
+        your_stack = extra_c_stack;
+        extra_c_stack = NULL;
     } else {
-        return create_stack(kernel, C_STACK_SIZE);
+        your_stack = cached_c_stack;
+        cached_c_stack = NULL;
     }
+    config_valgrind_stack(your_stack);
+    return your_stack;
 }
 
+// NB: Runs on the Rust stack
 void
 rust_task_thread::return_c_stack(stk_seg *stack) {
-    if (cached_c_stack) {
-        destroy_stack(kernel, stack);
-    } else {
+    I(this, !extra_c_stack);
+    unconfig_valgrind_stack(stack);
+    if (!cached_c_stack) {
         cached_c_stack = stack;
+    } else {
+        extra_c_stack = stack;
     }
 }