There is only one yield glue.

This commit is contained in:
Rafael Ávila de Espíndola 2011-05-24 18:23:39 -04:00
parent b1292580b9
commit ac836dd79c
7 changed files with 52 additions and 57 deletions

View File

@ -33,7 +33,7 @@ RUNTIME_CS := rt/sync/timer.cpp \
RUNTIME_LL := rt/new_exit.ll
RUNTIME_S := rt/activate_glue.s
RUNTIME_S := rt/activate_glue.s rt/yield_glue.s
RUNTIME_HDR := rt/globals.h \
rt/rust.h \

View File

@ -86,43 +86,6 @@ fn store_esp_to_runtime_sp_second_arg() -> vec[str] {
ret ["movl %esp, " + wstr(abi::task_field_runtime_sp) + "(%edx)"];
}
/* 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.
*
*/
fn rust_yield_glue() -> vec[str] {
ret ["movl 0(%esp), %ecx # ecx = rust_task"]
+ load_esp_from_rust_sp_first_arg()
+ save_callee_saves()
+ store_esp_to_rust_sp_first_arg()
+ load_esp_from_runtime_sp_first_arg()
+ restore_callee_saves()
+ ["ret"];
}
fn native_glue(int n_args, abi::native_glue_type ngt) -> vec[str] {
let bool pass_task;
@ -218,11 +181,8 @@ fn get_module_asm() -> str {
auto prefix = get_symbol_prefix();
auto glues =
[decl_glue(align, prefix,
abi::yield_glue_name(),
rust_yield_glue())]
let vec[str] glues =
[]
+ vec::init_fn[str](bind decl_native_glue(align, prefix,
abi::ngt_rust, _), (abi::n_native_glues + 1) as uint)
+ vec::init_fn[str](bind decl_native_glue(align, prefix,

View File

@ -7660,9 +7660,6 @@ fn create_crate_constant(ValueRef crate_ptr, @glue_fns glues) {
let ValueRef crate_addr = p2i(crate_ptr);
let ValueRef yield_glue_off =
llvm::LLVMConstSub(p2i(glues.yield_glue), crate_addr);
let ValueRef crate_val =
C_struct([C_null(T_int()), // ptrdiff_t image_base_off
p2i(crate_ptr), // uintptr_t self_addr
@ -7671,10 +7668,10 @@ fn create_crate_constant(ValueRef crate_ptr, @glue_fns glues) {
C_null(T_int()), // ptrdiff_t debug_info_off
C_null(T_int()), // size_t debug_info_sz
C_null(T_int()), // size_t pad
yield_glue_off, // size_t yield_glue_off
C_null(T_int()), // size_t pad
C_null(T_int()), // size_t gc_glue_off
C_null(T_int()), // size_t pad2
C_null(T_int()), // size_t gc_glue_off
C_null(T_int()), // size_t pad3
C_null(T_int()), // int n_rust_syms
C_null(T_int()), // int n_c_syms
C_null(T_int()) // int n_libs

View File

@ -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),

View File

@ -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

View File

@ -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

42
src/rt/yield_glue.s Normal file
View File

@ -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