diff options
| author | Brian Anderson <banderson@mozilla.com> | 2012-02-09 01:13:32 -0800 |
|---|---|---|
| committer | Brian Anderson <banderson@mozilla.com> | 2012-02-09 19:00:16 -0800 |
| commit | 79b1563abb32a385724bbe5ce6b4cdbee9ae5dc7 (patch) | |
| tree | baa648a32c783bc950299bc9d8e33201132366ee /src/rt/rust_task_thread.cpp | |
| parent | bfb80064d2dd37bd1e7009d98aa585253f5a2812 (diff) | |
| download | rust-79b1563abb32a385724bbe5ce6b4cdbee9ae5dc7.tar.gz rust-79b1563abb32a385724bbe5ce6b4cdbee9ae5dc7.zip | |
rt: Use rust_task_thread's C-stack pool for native calls
Diffstat (limited to 'src/rt/rust_task_thread.cpp')
| -rw-r--r-- | src/rt/rust_task_thread.cpp | 58 |
1 files changed, 45 insertions, 13 deletions
diff --git a/src/rt/rust_task_thread.cpp b/src/rt/rust_task_thread.cpp index 4129969057c..48bd7f16bdf 100644 --- a/src/rt/rust_task_thread.cpp +++ b/src/rt/rust_task_thread.cpp @@ -61,10 +61,6 @@ rust_task_thread::~rust_task_thread() { #ifndef __WIN32__ pthread_attr_destroy(&attr); #endif - - if (cached_c_stack) { - destroy_stack(kernel, cached_c_stack); - } } void @@ -72,7 +68,9 @@ rust_task_thread::activate(rust_task *task) { task->ctx.next = &c_context; DLOG(this, task, "descheduling..."); lock.unlock(); + prepare_c_stack(); task->ctx.swap(c_context); + unprepare_c_stack(); lock.lock(); DLOG(this, task, "task has returned"); } @@ -287,6 +285,13 @@ rust_task_thread::start_main_loop() { DLOG(this, dom, "finished main-loop %d", id); lock.unlock(); + + I(this, !extra_c_stack); + if (cached_c_stack) { + unconfig_valgrind_stack(cached_c_stack); + destroy_stack(kernel, cached_c_stack); + cached_c_stack = NULL; + } } rust_crate_cache * @@ -374,24 +379,51 @@ rust_task_thread::exit() { lock.signal(); } +// Before activating each task, make sure we have a C stack available. +// It needs to be allocated ahead of time (while we're on our own +// stack), because once we're on the Rust stack we won't have enough +// room to do the allocation +void +rust_task_thread::prepare_c_stack() { + I(this, !extra_c_stack); + if (!cached_c_stack) { + cached_c_stack = create_stack(kernel, C_STACK_SIZE); + } +} + +void +rust_task_thread::unprepare_c_stack() { + if (extra_c_stack) { + destroy_stack(kernel, extra_c_stack); + extra_c_stack = NULL; + } +} + +// NB: Runs on the Rust stack 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; + I(this, cached_c_stack); + stk_seg *your_stack; + if (extra_c_stack) { + your_stack = extra_c_stack; + extra_c_stack = NULL; } else { - return create_stack(kernel, C_STACK_SIZE); + your_stack = cached_c_stack; + cached_c_stack = NULL; } + config_valgrind_stack(your_stack); + return your_stack; } +// NB: Runs on the Rust stack void rust_task_thread::return_c_stack(stk_seg *stack) { - if (cached_c_stack) { - destroy_stack(kernel, stack); - } else { + I(this, !extra_c_stack); + unconfig_valgrind_stack(stack); + if (!cached_c_stack) { cached_c_stack = stack; + } else { + extra_c_stack = stack; } } |
