From 9bcbd965dc7ef0f4d79f3d0302444b72b4b42a1f Mon Sep 17 00:00:00 2001 From: Avi Kivity <avi.kivity@gmail.com> Date: Wed, 2 Jan 2013 17:48:08 +0200 Subject: [PATCH] sched: switch main thread stack from original stack This way everyone's running on a similar sized stack. Theoretically the main thread can be destroyed as well. --- arch/x64/arch-switch.hh | 15 +++++++++++++++ arch/x64/entry.S | 13 +++++++++++++ loader.cc | 2 +- sched.cc | 4 ++-- sched.hh | 2 ++ 5 files changed, 33 insertions(+), 3 deletions(-) diff --git a/arch/x64/arch-switch.hh b/arch/x64/arch-switch.hh index 09ddce5b0..3ed343969 100644 --- a/arch/x64/arch-switch.hh +++ b/arch/x64/arch-switch.hh @@ -7,6 +7,8 @@ extern "C" { void thread_main(void); void thread_main_c(sched::thread* t); +void stack_trampoline(sched::thread* t, void (*func)(sched::thread*), + void** stacktop); } namespace sched { @@ -37,6 +39,19 @@ void thread::init_stack() _state.rsp = stacktop; } +void thread::switch_to_thread_stack() +{ + void** stacktop = reinterpret_cast<void**>(_stack + sizeof(_stack)); + stack_trampoline(this, &thread::on_thread_stack, stacktop); +} + +void thread::on_thread_stack(thread* t) +{ + t->_func(); + t->_waiting = true; + schedule(); +} + void thread::setup_tcb() { // FIXME: respect alignment diff --git a/arch/x64/entry.S b/arch/x64/entry.S index a99cd3820..849cd9511 100644 --- a/arch/x64/entry.S +++ b/arch/x64/entry.S @@ -100,3 +100,16 @@ thread_main: pop %rdi call thread_main_c .cfi_endproc + +.global stack_trampoline +stack_trampoline: # %rsi=arg, %rdi=func, %rdx=stack + .cfi_startproc simple + .cfi_def_cfa %rsp, 0 + mov %rsp, -8(%rdx) + lea -8(%rdx), %rsp + .cfi_rel_offset %rsp, 0 + call *%rsi + pop %rsp + .cfi_restore %rsp + ret + .cfi_endproc diff --git a/loader.cc b/loader.cc index a10f74bbb..fd9c571d9 100644 --- a/loader.cc +++ b/loader.cc @@ -157,7 +157,7 @@ int main(int ac, char **av) void main_thread(elf::program& prog) { - new thread([] { test_threads(); }); + test_threads(); prog.add("libjvm.so"); auto JNI_GetDefaultJavaVMInitArgs = prog.lookup_function<void (void*)>("JNI_GetDefaultJavaVMInitArgs"); diff --git a/sched.cc b/sched.cc index f39bd0156..0131a7c61 100644 --- a/sched.cc +++ b/sched.cc @@ -34,7 +34,7 @@ void schedule() thread::thread(std::function<void ()> func, bool main) : _func(func) - , _on_runqueue(true) + , _on_runqueue(!main) , _waiting(false) { if (!main) { @@ -44,7 +44,7 @@ thread::thread(std::function<void ()> func, bool main) } else { setup_tcb_main(); s_current = this; - func(); + switch_to_thread_stack(); abort(); } } diff --git a/sched.hh b/sched.hh index 323137a56..19958a14b 100644 --- a/sched.hh +++ b/sched.hh @@ -32,6 +32,8 @@ private: void init_stack(); void setup_tcb(); void setup_tcb_main(); + static void on_thread_stack(thread* t); + void switch_to_thread_stack(); private: std::function<void ()> _func; thread_state _state; -- GitLab