From 0bd492c6bf0d8199a6783184f2599968ac328ca8 Mon Sep 17 00:00:00 2001 From: normal Date: Wed, 15 Oct 2014 22:34:43 +0000 Subject: cont.c: Code cleanup in fiber_switch/fiber_store Defragment code blocks depending on FIBER_USE_NATIVE in order to make the control flow (which is already non-trivial due to nonlocal jumps) in each case more comprehensible. Remove some unreachable code from fiber_switch (we've already excluded the case (th->fiber == fibval) at the start of the function). Remove call to rb_fiber_current which happened a few lines after accessing GET_THREAD()->fiber directly (so if that's ever 0 we're already screwed). Author: Knut Franke * cont.c (fiber_store, fiber_switch): simplify [ruby-core:65518] [Feature #10341] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@47961 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 5 ++++ cont.c | 83 +++++++++++++++++++++++++++++++-------------------------------- 2 files changed, 46 insertions(+), 42 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2254c931fa..99c0708f0f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Thu Oct 16 05:02:31 2014 Knut Franke + + * cont.c (fiber_store, fiber_switch): simplify + [ruby-core:65518] [Feature #10341] + Thu Oct 16 04:28:41 2014 Knut Franke * cont.c (rb_fiber_t): remove prev_fiber/next_fiber diff --git a/cont.c b/cont.c index 412f20a9ef..49b7702ae8 100644 --- a/cont.c +++ b/cont.c @@ -1337,43 +1337,50 @@ fiber_store(rb_fiber_t *next_fib) th->root_fiber = th->fiber = fib->cont.self; } -#if !FIBER_USE_NATIVE - cont_save_machine_stack(th, &fib->cont); -#endif - - if (FIBER_USE_NATIVE || ruby_setjmp(fib->cont.jmpbuf)) { #if FIBER_USE_NATIVE - fiber_setcontext(next_fib, fib); + fiber_setcontext(next_fib, fib); + /* restored */ #ifndef _WIN32 - if (terminated_machine_stack.ptr) { - if (machine_stack_cache_index < MAX_MACHINE_STACK_CACHE) { - machine_stack_cache[machine_stack_cache_index].ptr = terminated_machine_stack.ptr; - machine_stack_cache[machine_stack_cache_index].size = terminated_machine_stack.size; - machine_stack_cache_index++; + if (terminated_machine_stack.ptr) { + if (machine_stack_cache_index < MAX_MACHINE_STACK_CACHE) { + machine_stack_cache[machine_stack_cache_index].ptr = terminated_machine_stack.ptr; + machine_stack_cache[machine_stack_cache_index].size = terminated_machine_stack.size; + machine_stack_cache_index++; + } + else { + if (terminated_machine_stack.ptr != fib->cont.machine.stack) { + munmap((void*)terminated_machine_stack.ptr, terminated_machine_stack.size * sizeof(VALUE)); } else { - if (terminated_machine_stack.ptr != fib->cont.machine.stack) { - munmap((void*)terminated_machine_stack.ptr, terminated_machine_stack.size * sizeof(VALUE)); - } - else { - rb_bug("terminated fiber resumed"); - } + rb_bug("terminated fiber resumed"); } - terminated_machine_stack.ptr = NULL; - terminated_machine_stack.size = 0; } -#endif -#endif + terminated_machine_stack.ptr = NULL; + terminated_machine_stack.size = 0; + } + GetFiberPtr(th->fiber, fib); + if (fib->cont.argc == -1) rb_exc_raise(fib->cont.value); + return fib->cont.value; +#endif /* not _WIN32 */ + +#else /* FIBER_USE_NATIVE */ + cont_save_machine_stack(th, &fib->cont); + if (ruby_setjmp(fib->cont.jmpbuf)) { /* restored */ GetFiberPtr(th->fiber, fib); if (fib->cont.argc == -1) rb_exc_raise(fib->cont.value); + if (nextfib->cont.value == Qundef) { + cont_restore_0(nextfib->cont, &nextfib->cont.value); + rb_bug("rb_fiber_resume: unreachable"); + } return fib->cont.value; } -#if !FIBER_USE_NATIVE else { - return Qundef; + VALUE undef = Qundef; + cont_restore_0(nextfib->cont, &undef); + rb_bug("rb_fiber_resume: unreachable"); } -#endif +#endif /* FIBER_USE_NATIVE */ } static inline VALUE @@ -1402,30 +1409,28 @@ fiber_switch(VALUE fibval, int argc, const VALUE *argv, int is_resume) } else if (fib->status == TERMINATED) { value = rb_exc_new2(rb_eFiberError, "dead fiber called"); - if (th->fiber != fibval) { - GetFiberPtr(th->fiber, fib); - if (fib->status != TERMINATED) rb_exc_raise(value); - fibval = th->root_fiber; - } - else { - fibval = fib->prev; - if (NIL_P(fibval)) fibval = th->root_fiber; - } - GetFiberPtr(fibval, fib); + + GetFiberPtr(th->fiber, fib); + if (fib->status != TERMINATED) rb_exc_raise(value); + + /* th->fiber is also dead => switch to root fiber */ + /* (this means we're being called from rb_fiber_terminate, */ + /* and the terminated fiber's return_fiber() is already dead) */ + GetFiberPtr(th->root_fiber, fib); cont = &fib->cont; cont->argc = -1; cont->value = value; #if FIBER_USE_NATIVE { - VALUE oldfibval; + VALUE oldfibval = th->fiber; rb_fiber_t *oldfib; - oldfibval = rb_fiber_current(); GetFiberPtr(oldfibval, oldfib); fiber_setcontext(fib, oldfib); } #else cont_restore_0(cont, &value); #endif + /* unreachable */ } if (is_resume) { @@ -1440,12 +1445,6 @@ fiber_switch(VALUE fibval, int argc, const VALUE *argv, int is_resume) cont->value = make_passing_arg(argc, argv); value = fiber_store(fib); -#if !FIBER_USE_NATIVE - if (value == Qundef) { - cont_restore_0(cont, &value); - rb_bug("rb_fiber_resume: unreachable"); - } -#endif RUBY_VM_CHECK_INTS(th); return value; -- cgit v1.2.3