From ac836dd79c2d7c631ca601dc468de13cb5c785da Mon Sep 17 00:00:00 2001 From: Rafael Ávila de Espíndola Date: Tue, 24 May 2011 18:23:39 -0400 Subject: There is only one yield glue. --- src/rt/rust_crate.cpp | 5 ----- src/rt/rust_internal.h | 5 ++--- src/rt/rust_task.cpp | 4 +++- src/rt/yield_glue.s | 42 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 47 insertions(+), 9 deletions(-) create mode 100644 src/rt/yield_glue.s (limited to 'src/rt') diff --git a/src/rt/rust_crate.cpp b/src/rt/rust_crate.cpp index 6783d43c04c..2e312c8c564 100644 --- a/src/rt/rust_crate.cpp +++ b/src/rt/rust_crate.cpp @@ -16,11 +16,6 @@ rust_crate::get_gc_glue() const { return ((uintptr_t)this + gc_glue_off); } -uintptr_t -rust_crate::get_yield_glue() const { - return ((uintptr_t)this + yield_glue_off); -} - rust_crate::mem_area::mem_area(rust_dom *dom, uintptr_t pos, size_t sz) : dom(dom), base(pos), diff --git a/src/rt/rust_internal.h b/src/rt/rust_internal.h index 6bd638ed469..03022812a09 100644 --- a/src/rt/rust_internal.h +++ b/src/rt/rust_internal.h @@ -232,10 +232,10 @@ class rust_crate { size_t debug_info_sz; // Size of .debug_info. ptrdiff_t activate_glue_off; - ptrdiff_t yield_glue_off; ptrdiff_t pad; - ptrdiff_t gc_glue_off; ptrdiff_t pad2; + ptrdiff_t gc_glue_off; + ptrdiff_t pad3; public: @@ -247,7 +247,6 @@ public: uintptr_t get_image_base() const; ptrdiff_t get_relocation_diff() const; - uintptr_t get_yield_glue() const; uintptr_t get_gc_glue() const; struct mem_area diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp index db72be6d12d..bd57eb89cca 100644 --- a/src/rt/rust_task.cpp +++ b/src/rt/rust_task.cpp @@ -317,12 +317,14 @@ rust_task::yield(size_t nargs) { yield(nargs, 0); } +extern "C" void new_rust_yield_glue(void) asm("new_rust_yield_glue"); + void rust_task::yield(size_t nargs, size_t time_in_us) { LOG(this, task, "task %s @0x%" PRIxPTR " yielding for %d us", name, this, time_in_us); yield_timer.reset(time_in_us); - run_after_return(nargs, dom->root_crate->get_yield_glue()); + run_after_return(nargs, (uintptr_t) new_rust_yield_glue); } static inline uintptr_t diff --git a/src/rt/yield_glue.s b/src/rt/yield_glue.s new file mode 100644 index 00000000000..767c9c5cae6 --- /dev/null +++ b/src/rt/yield_glue.s @@ -0,0 +1,42 @@ +/* More glue code, this time the 'bottom half' of yielding. + * + * We arrived here because an native call decided to deschedule the + * running task. So the native call's return address got patched to the + * first instruction of this glue code. + * + * When the native call does 'ret' it will come here, and its esp will be + * pointing to the last argument pushed on the C stack before making + * the native call: the 0th argument to the native call, which is always + * the task ptr performing the native call. That's where we take over. + * + * Our goal is to complete the descheduling + * + * - Switch over to the task stack temporarily. + * + * - Save the task's callee-saves onto the task stack. + * (the task is now 'descheduled', safe to set aside) + * + * - Switch *back* to the C stack. + * + * - Restore the C-stack callee-saves. + * + * - Return to the caller on the C stack that activated the task. + * + */ + + .globl new_rust_yield_glue + .balign 4 +new_rust_yield_glue: + movl 0(%esp), %ecx # ecx = rust_task + movl 16(%ecx), %esp + pushl %ebp + pushl %edi + pushl %esi + pushl %ebx + movl %esp, 16(%ecx) + movl 12(%ecx), %esp + popl %ebx + popl %esi + popl %edi + popl %ebp + ret -- cgit 1.4.1-3-g733a5