about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2012-02-08 22:53:58 -0800
committerBrian Anderson <banderson@mozilla.com>2012-02-09 19:00:16 -0800
commitbfb80064d2dd37bd1e7009d98aa585253f5a2812 (patch)
treebec247b9a873be925ebd3ef35ea52018d499a03b
parent8fe506bdca714fe2b8b005b1d190091d221c4044 (diff)
downloadrust-bfb80064d2dd37bd1e7009d98aa585253f5a2812.tar.gz
rust-bfb80064d2dd37bd1e7009d98aa585253f5a2812.zip
rt: Add methods to rust_task_thread for borrowing C stacks
-rw-r--r--src/rt/rust_task_thread.cpp30
-rw-r--r--src/rt/rust_task_thread.h11
2 files changed, 40 insertions, 1 deletions
diff --git a/src/rt/rust_task_thread.cpp b/src/rt/rust_task_thread.cpp
index 41242fee9d3..4129969057c 100644
--- a/src/rt/rust_task_thread.cpp
+++ b/src/rt/rust_task_thread.cpp
@@ -13,6 +13,8 @@ pthread_key_t rust_task_thread::task_key;
 DWORD rust_task_thread::task_key;
 #endif
 
+const size_t C_STACK_SIZE = (1024*1024);
+
 bool rust_task_thread::tls_initialized = false;
 
 rust_task_thread::rust_task_thread(rust_scheduler *sched,
@@ -34,7 +36,8 @@ rust_task_thread::rust_task_thread(rust_scheduler *sched,
     id(id),
     min_stack_size(kernel->env->min_stack_size),
     env(kernel->env),
-    should_exit(false)
+    should_exit(false),
+    cached_c_stack(NULL)
 {
     LOGPTR(this, "new dom", (uintptr_t)this);
     isaac_init(kernel, &rctx);
@@ -58,6 +61,10 @@ rust_task_thread::~rust_task_thread() {
 #ifndef __WIN32__
     pthread_attr_destroy(&attr);
 #endif
+
+    if (cached_c_stack) {
+        destroy_stack(kernel, cached_c_stack);
+    }
 }
 
 void
@@ -367,6 +374,27 @@ rust_task_thread::exit() {
     lock.signal();
 }
 
+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;
+    } else {
+        return create_stack(kernel, C_STACK_SIZE);
+    }
+}
+
+void
+rust_task_thread::return_c_stack(stk_seg *stack) {
+    if (cached_c_stack) {
+        destroy_stack(kernel, stack);
+    } else {
+        cached_c_stack = stack;
+    }
+}
+
 //
 // Local Variables:
 // mode: C++
diff --git a/src/rt/rust_task_thread.h b/src/rt/rust_task_thread.h
index 541d95f6460..360e4e44e0b 100644
--- a/src/rt/rust_task_thread.h
+++ b/src/rt/rust_task_thread.h
@@ -1,6 +1,7 @@
 #ifndef RUST_TASK_THREAD_H
 #define RUST_TASK_THREAD_H
 
+#include "rust_stack.h"
 #include "context.h"
 
 #ifndef _WIN32
@@ -91,6 +92,12 @@ struct rust_task_thread : public kernel_owned<rust_task_thread>,
 
     bool should_exit;
 
+private:
+
+    stk_seg *cached_c_stack;
+
+public:
+
     // Only a pointer to 'name' is kept, so it must live as long as this
     // domain.
     rust_task_thread(rust_scheduler *sched, rust_srv *srv, int id);
@@ -127,6 +134,10 @@ struct rust_task_thread : public kernel_owned<rust_task_thread>,
 
     // Tells the scheduler to exit it's scheduling loop and thread
     void exit();
+
+    // Called by tasks when they need a stack on which to run C code
+    stk_seg *borrow_c_stack();
+    void return_c_stack(stk_seg *stack);
 };
 
 inline rust_log &