about summary refs log tree commit diff
path: root/src/rt/rust_upcall.cpp
diff options
context:
space:
mode:
authorEric Holk <eholk@mozilla.com>2011-05-31 17:44:54 -0700
committerGraydon Hoare <graydon@mozilla.com>2011-06-13 18:14:13 -0700
commitd1857d30fc05f29fb82231336b229e50948a8336 (patch)
tree8a1ad8ad6dcda631e4858902008e3d7b8227b271 /src/rt/rust_upcall.cpp
parent1595c9d767de72340358028e87d3eb386af0adfe (diff)
downloadrust-d1857d30fc05f29fb82231336b229e50948a8336.tar.gz
rust-d1857d30fc05f29fb82231336b229e50948a8336.zip
This is the mega-ucontext commit. It replaces the task switching mechanism with a new one inspired by ucontext. It works under Linux, OS X and Windows, and is Valgrind clean on Linux and OS X (provided the runtime is built with gcc).
This commit also moves yield and join to the standard library, as requested in #42. Join is currently a no-op though.
Diffstat (limited to 'src/rt/rust_upcall.cpp')
-rw-r--r--src/rt/rust_upcall.cpp22
1 files changed, 20 insertions, 2 deletions
diff --git a/src/rt/rust_upcall.cpp b/src/rt/rust_upcall.cpp
index 6d8734bd430..fb7e3edc4f8 100644
--- a/src/rt/rust_upcall.cpp
+++ b/src/rt/rust_upcall.cpp
@@ -462,11 +462,22 @@ upcall_new_task(rust_task *spawner, rust_vec *name) {
     return task;
 }
 
+// TODO: This is copied from rust_task.cpp. Both copies should be moved to a
+// common location.
+static uintptr_t
+align_down(uintptr_t sp)
+{
+    // There is no platform we care about that needs more than a
+    // 16-byte alignment.
+    return sp & ~(16 - 1);
+}
+
 extern "C" CDECL rust_task *
 upcall_start_task(rust_task *spawner,
                   rust_task *task,
                   uintptr_t spawnee_fn,
-                  uintptr_t args) {
+                  uintptr_t args,
+                  size_t args_sz) {
     LOG_UPCALL_ENTRY(spawner);
 
     rust_dom *dom = spawner->dom;
@@ -478,7 +489,14 @@ upcall_start_task(rust_task *spawner,
 
     // we used to be generating this tuple in rustc, but it's easier to do it
     // here.
-    uintptr_t start_args[] = {0, 0, 0, args};
+    //
+    // The args tuple is stack-allocated. We need to move it over to the new
+    // stack.
+    task->rust_sp -= args_sz;
+    memcpy((void*)task->rust_sp, (void*)args, args_sz);
+    uintptr_t start_args[] = {0, 0, 0, task->rust_sp};
+    
+    task->rust_sp = align_down(task->rust_sp);
     
     task->start(spawnee_fn, (uintptr_t)start_args, sizeof(start_args));
     return task;