diff options
| author | Eric Holk <eholk@mozilla.com> | 2011-05-31 17:44:54 -0700 |
|---|---|---|
| committer | Graydon Hoare <graydon@mozilla.com> | 2011-06-13 18:14:13 -0700 |
| commit | d1857d30fc05f29fb82231336b229e50948a8336 (patch) | |
| tree | 8a1ad8ad6dcda631e4858902008e3d7b8227b271 /src/rt/rust_upcall.cpp | |
| parent | 1595c9d767de72340358028e87d3eb386af0adfe (diff) | |
| download | rust-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.cpp | 22 |
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; |
