ruby-changes:35879
From: normal <ko1@a...>
Date: Thu, 16 Oct 2014 07:35:02 +0900 (JST)
Subject: [ruby-changes:35879] normal:r47961 (trunk): cont.c: Code cleanup in fiber_switch/fiber_store
normal 2014-10-16 07:34:43 +0900 (Thu, 16 Oct 2014) New Revision: 47961 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=47961 Log: 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 <Knut.Franke@g...> * cont.c (fiber_store, fiber_switch): simplify [ruby-core:65518] [Feature #10341] Modified files: trunk/ChangeLog trunk/cont.c Index: ChangeLog =================================================================== --- ChangeLog (revision 47960) +++ ChangeLog (revision 47961) @@ -1,3 +1,8 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Thu Oct 16 05:02:31 2014 Knut Franke <Knut.Franke@g...> + + * cont.c (fiber_store, fiber_switch): simplify + [ruby-core:65518] [Feature #10341] + Thu Oct 16 04:28:41 2014 Knut Franke <Knut.Franke@g...> * cont.c (rb_fiber_t): remove prev_fiber/next_fiber Index: cont.c =================================================================== --- cont.c (revision 47960) +++ cont.c (revision 47961) @@ -1337,43 +1337,50 @@ fiber_store(rb_fiber_t *next_fib) https://github.com/ruby/ruby/blob/trunk/cont.c#L1337 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, con https://github.com/ruby/ruby/blob/trunk/cont.c#L1409 } 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, con https://github.com/ruby/ruby/blob/trunk/cont.c#L1445 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; -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/