[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]