summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornormal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-10-15 22:34:43 +0000
committernormal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-10-15 22:34:43 +0000
commit0bd492c6bf0d8199a6783184f2599968ac328ca8 (patch)
tree13d8797e7f4b9741db2360938d47ec3318069bc6
parent9766fc4d707b7d6c7f3258a659cdec7be51964fd (diff)
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@gmx.de> * 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
-rw-r--r--ChangeLog5
-rw-r--r--cont.c83
2 files changed, 46 insertions, 42 deletions
diff --git a/ChangeLog b/ChangeLog
index 2254c93..99c0708 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Thu Oct 16 05:02:31 2014 Knut Franke <Knut.Franke@gmx.de>
+
+ * cont.c (fiber_store, fiber_switch): simplify
+ [ruby-core:65518] [Feature #10341]
+
Thu Oct 16 04:28:41 2014 Knut Franke <Knut.Franke@gmx.de>
* cont.c (rb_fiber_t): remove prev_fiber/next_fiber
diff --git a/cont.c b/cont.c
index 412f20a..49b7702 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;