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

ruby-changes:34114

From: normal <ko1@a...>
Date: Wed, 28 May 2014 10:48:23 +0900 (JST)
Subject: [ruby-changes:34114] normal:r46195 (trunk): vm.c: remove rb_vm_living_threads_foreach function

normal	2014-05-28 10:48:11 +0900 (Wed, 28 May 2014)

  New Revision: 46195

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=46195

  Log:
    vm.c: remove rb_vm_living_threads_foreach function
    
    Shorter code with fewer callbacks and casts should be more readable.
    
    * vm.c (rb_vm_living_threads_foreach): remove function
      [ruby-core:62745]
    * thread.c (terminate_i): remove
    * thread.c (terminate_all): implement (inlines old terminate_i)
    * thread.c (rb_thread_terminate_all): use terminate_all
    * thread.c (rb_thread_fd_close_i): remove
    * thread.c (rb_thread_fd_close): iterate inline
    * thread.c (thread_list_i): remove
    * thread.c (rb_thread_list): iterate inline
    * thread.c (rb_thread_atfork_internal): iterate inline
    * thread.c (terminate_atfork_i): update types to remove casts
    * thread.c (terminate_atfork_before_exec_i): ditto
    * thread.c (struct thgroup_list_params): remove definition
    * thread.c (thgroup_list_i): remove
    * thread.c (thgroup_list): iterate inline
    * thread.c (check_deadlock_i): remove
    * thread.c (debug_deadlock_check): implement (inlines check_deadlock_i)
    * thread.c (debug_i): remove
    * thread.c (rb_check_deadlock): iterate inline
    * vm.c (vm_mark_each_thread_func): remove
    * vm.c (rb_vm_mark): iterate inline
    * vm_core.h (rb_vm_living_threads_remove): remove
    * vm_trace.c (clear_trace_func_i): remove
    * vm_trace.c (rb_clear_trace_func): iterate inline

  Modified files:
    trunk/ChangeLog
    trunk/thread.c
    trunk/vm.c
    trunk/vm_core.h
    trunk/vm_trace.c
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 46194)
+++ ChangeLog	(revision 46195)
@@ -1,3 +1,30 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Wed May 28 10:29:28 2014  Eric Wong  <e@8...>
+
+	* vm.c (rb_vm_living_threads_foreach): remove function
+	  [ruby-core:62745]
+	* thread.c (terminate_i): remove
+	* thread.c (terminate_all): implement (inlines old terminate_i)
+	* thread.c (rb_thread_terminate_all): use terminate_all
+	* thread.c (rb_thread_fd_close_i): remove
+	* thread.c (rb_thread_fd_close): iterate inline
+	* thread.c (thread_list_i): remove
+	* thread.c (rb_thread_list): iterate inline
+	* thread.c (rb_thread_atfork_internal): iterate inline
+	* thread.c (terminate_atfork_i): update types to remove casts
+	* thread.c (terminate_atfork_before_exec_i): ditto
+	* thread.c (struct thgroup_list_params): remove definition
+	* thread.c (thgroup_list_i): remove
+	* thread.c (thgroup_list): iterate inline
+	* thread.c (check_deadlock_i): remove
+	* thread.c (debug_deadlock_check): implement (inlines check_deadlock_i)
+	* thread.c (debug_i): remove
+	* thread.c (rb_check_deadlock): iterate inline
+	* vm.c (vm_mark_each_thread_func): remove
+	* vm.c (rb_vm_mark): iterate inline
+	* vm_core.h (rb_vm_living_threads_remove): remove
+	* vm_trace.c (clear_trace_func_i): remove
+	* vm_trace.c (rb_clear_trace_func): iterate inline
+
 Wed May 28 09:30:51 2014  Eric Wong  <e@8...>
 
 	* signal.c (signal_exec): ignore immediate cmd for SIG_IGN
Index: vm_core.h
===================================================================
--- vm_core.h	(revision 46194)
+++ vm_core.h	(revision 46195)
@@ -886,7 +886,6 @@ rb_vm_living_threads_remove(rb_vm_t *vm, https://github.com/ruby/ruby/blob/trunk/vm_core.h#L886
     vm->living_thread_num--;
 }
 
-void rb_vm_living_threads_foreach(rb_vm_t*, int (*)(rb_thread_t*, void*), void*);
 int ruby_thread_has_gvl_p(void);
 typedef int rb_backtrace_iter_func(void *, VALUE, int, VALUE);
 rb_control_frame_t *rb_vm_get_ruby_level_next_cfp(rb_thread_t *th, const rb_control_frame_t *cfp);
Index: thread.c
===================================================================
--- thread.c	(revision 46194)
+++ thread.c	(revision 46195)
@@ -368,18 +368,21 @@ rb_threadptr_trap_interrupt(rb_thread_t https://github.com/ruby/ruby/blob/trunk/thread.c#L368
     rb_threadptr_interrupt_common(th, 1);
 }
 
-static int
-terminate_i(rb_thread_t *th, void *main_thread)
+static void
+terminate_all(rb_vm_t *vm, const rb_thread_t *main_thread)
 {
-    if (th != main_thread) {
-	thread_debug("terminate_i: %p\n", (void *)th);
-	rb_threadptr_pending_interrupt_enque(th, eTerminateSignal);
-	rb_threadptr_interrupt(th);
-    }
-    else {
-	thread_debug("terminate_i: main thread (%p)\n", (void *)th);
+    rb_thread_t *th;
+
+    list_for_each(&vm->living_threads, th, vmlt_node) {
+	if (th != main_thread) {
+	    thread_debug("terminate_i: %p\n", (void *)th);
+	    rb_threadptr_pending_interrupt_enque(th, eTerminateSignal);
+	    rb_threadptr_interrupt(th);
+	}
+	else {
+	    thread_debug("terminate_i: main thread (%p)\n", (void *)th);
+	}
     }
-    return ST_CONTINUE;
 }
 
 typedef struct rb_mutex_struct
@@ -430,7 +433,7 @@ rb_thread_terminate_all(void) https://github.com/ruby/ruby/blob/trunk/thread.c#L433
 
   retry:
     thread_debug("rb_thread_terminate_all (main thread: %p)\n", (void *)th);
-    rb_vm_living_threads_foreach(vm, terminate_i, th);
+    terminate_all(vm, th);
 
     while (!rb_thread_alone()) {
 	int state;
@@ -2063,22 +2066,19 @@ rb_threadptr_reset_raised(rb_thread_t *t https://github.com/ruby/ruby/blob/trunk/thread.c#L2066
     return 1;
 }
 
-static int
-thread_fd_close_i(rb_thread_t *th, void *fdp)
-{
-    int *fd = fdp;
-    if (th->waiting_fd == *fd) {
-	VALUE err = th->vm->special_exceptions[ruby_error_closed_stream];
-	rb_threadptr_pending_interrupt_enque(th, err);
-	rb_threadptr_interrupt(th);
-    }
-    return ST_CONTINUE;
-}
-
 void
 rb_thread_fd_close(int fd)
 {
-    rb_vm_living_threads_foreach(GET_THREAD()->vm, thread_fd_close_i, &fd);
+    rb_vm_t *vm = GET_THREAD()->vm;
+    rb_thread_t *th;
+
+    list_for_each(&vm->living_threads, th, vmlt_node) {
+	if (th->waiting_fd == fd) {
+	    VALUE err = th->vm->special_exceptions[ruby_error_closed_stream];
+	    rb_threadptr_pending_interrupt_enque(th, err);
+	    rb_threadptr_interrupt(th);
+	}
+    }
 }
 
 /*
@@ -2297,22 +2297,6 @@ rb_thread_stop(void) https://github.com/ruby/ruby/blob/trunk/thread.c#L2297
     return Qnil;
 }
 
-static int
-thread_list_i(rb_thread_t *th, void *data)
-{
-    VALUE ary = (VALUE)data;
-
-    switch (th->status) {
-      case THREAD_RUNNABLE:
-      case THREAD_STOPPED:
-      case THREAD_STOPPED_FOREVER:
-	rb_ary_push(ary, th->self);
-      default:
-	break;
-    }
-    return ST_CONTINUE;
-}
-
 /********************************************************************/
 
 /*
@@ -2339,7 +2323,19 @@ VALUE https://github.com/ruby/ruby/blob/trunk/thread.c#L2323
 rb_thread_list(void)
 {
     VALUE ary = rb_ary_new();
-    rb_vm_living_threads_foreach(GET_THREAD()->vm, thread_list_i, (void *)ary);
+    rb_vm_t *vm = GET_THREAD()->vm;
+    rb_thread_t *th;
+
+    list_for_each(&vm->living_threads, th, vmlt_node) {
+	switch (th->status) {
+	  case THREAD_RUNNABLE:
+	  case THREAD_STOPPED:
+	  case THREAD_STOPPED_FOREVER:
+	    rb_ary_push(ary, th->self);
+	  default:
+	    break;
+	}
+    }
     return ary;
 }
 
@@ -3771,29 +3767,32 @@ clear_coverage(void) https://github.com/ruby/ruby/blob/trunk/thread.c#L3767
 }
 
 static void
-rb_thread_atfork_internal(int (*atfork)(rb_thread_t *, void *))
+rb_thread_atfork_internal(void (*atfork)(rb_thread_t *, const rb_thread_t *))
 {
     rb_thread_t *th = GET_THREAD();
+    rb_thread_t *i;
     rb_vm_t *vm = th->vm;
     vm->main_thread = th;
 
     gvl_atfork(th->vm);
-    rb_vm_living_threads_foreach(vm, atfork, th);
+
+    list_for_each(&vm->living_threads, i, vmlt_node) {
+	atfork(i, th);
+    }
     rb_vm_living_threads_init(vm);
     rb_vm_living_threads_insert(vm, th);
     vm->sleeper = 0;
     clear_coverage();
 }
 
-static int
-terminate_atfork_i(rb_thread_t *th, void *current_th)
+static void
+terminate_atfork_i(rb_thread_t *th, const rb_thread_t *current_th)
 {
-    if (th != (rb_thread_t *)current_th) {
+    if (th != current_th) {
 	rb_mutex_abandon_keeping_mutexes(th);
 	rb_mutex_abandon_locking_mutex(th);
 	thread_cleanup_func(th, TRUE);
     }
-    return ST_CONTINUE;
 }
 
 void
@@ -3806,13 +3805,12 @@ rb_thread_atfork(void) https://github.com/ruby/ruby/blob/trunk/thread.c#L3805
     rb_reset_random_seed();
 }
 
-static int
-terminate_atfork_before_exec_i(rb_thread_t *th, void *current_th)
+static void
+terminate_atfork_before_exec_i(rb_thread_t *th, const rb_thread_t *current_th)
 {
-    if (th != (rb_thread_t *)current_th) {
+    if (th != current_th) {
 	thread_cleanup_func_before_exec(th);
     }
-    return ST_CONTINUE;
 }
 
 void
@@ -3870,25 +3868,6 @@ thgroup_s_alloc(VALUE klass) https://github.com/ruby/ruby/blob/trunk/thread.c#L3868
     return group;
 }
 
-struct thgroup_list_params {
-    VALUE ary;
-    VALUE group;
-};
-
-static int
-thgroup_list_i(rb_thread_t *th, void *arg)
-{
-    struct thgroup_list_params *params = arg;
-    VALUE thread = th->self;
-    VALUE ary = params->ary;
-    VALUE group = params->group;
-
-    if (th->thgroup == group) {
-	rb_ary_push(ary, thread);
-    }
-    return ST_CONTINUE;
-}
-
 /*
  *  call-seq:
  *     thgrp.list   -> array
@@ -3902,11 +3881,14 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/thread.c#L3881
 thgroup_list(VALUE group)
 {
     VALUE ary = rb_ary_new();
-    struct thgroup_list_params param;
+    rb_vm_t *vm = GET_THREAD()->vm;
+    rb_thread_t *th;
 
-    param.ary = ary;
-    param.group = group;
-    rb_vm_living_threads_foreach(GET_THREAD()->vm, thgroup_list_i, &param);
+    list_for_each(&vm->living_threads, th, vmlt_node) {
+	if (th->thgroup == group) {
+	    rb_ary_push(ary, th->self);
+	}
+    }
     return ary;
 }
 
@@ -5044,66 +5026,62 @@ ruby_native_thread_p(void) https://github.com/ruby/ruby/blob/trunk/thread.c#L5026
     return th != 0;
 }
 
-static int
-check_deadlock_i(rb_thread_t *th, void *arg)
+static void
+debug_deadlock_check(rb_vm_t *vm)
 {
-    int *found = arg;
-    if (th->status != THREAD_STOPPED_FOREVER || RUBY_VM_INTERRUPTED(th)) {
-	*found = 1;
-    }
-    else if (th->locking_mutex) {
-	rb_mutex_t *mutex;
-	GetMutexPtr(th->locking_mutex, mutex);
-
-	native_mutex_lock(&mutex->lock);
-	if (mutex->th == th || (!mutex->th && mutex->cond_waiting)) {
-	    *found = 1;
-	}
-	native_mutex_unlock(&mutex->lock);
-    }
+#ifdef DEBUG_DEADLOCK_CHECK
+    rb_thread_t *th;
 
-    return (*found) ? ST_STOP : ST_CONTINUE;
-}
+    printf("%d %d %p %p\n", vm_living_thread_num(vm), vm->sleeper, GET_THREAD(), vm->main_thread);
+    list_for_each(&vm->living_threads, th, vmlt_node) {
+	printf("th:%p %d %d", th, th->status, th->interrupt_flag);
+	if (th->locking_mutex) {
+	    rb_mutex_t *mutex;
+	    GetMutexPtr(th->locking_mutex, mutex);
 
-#ifdef DEBUG_DEADLOCK_CHECK
-static int
-debug_i(rb_thread_t *th, int *found)
-{
-    printf("th:%p %d %d", th, th->status, th->interrupt_flag);
-    if (th->locking_mutex) {
-	rb_mutex_t *mutex;
-	GetMutexPtr(th->locking_mutex, mutex);
-
-	native_mutex_lock(&mutex->lock);
-	printf(" %p %d\n", mutex->th, mutex->cond_waiting);
-	native_mutex_unlock(&mutex->lock);
+	    native_mutex_lock(&mutex->lock);
+	    printf(" %p %d\n", mutex->th, mutex->cond_waiting);
+	    native_mutex_unlock(&mutex->lock);
+	}
+	else
+	    puts("");
     }
-    else
-	puts("");
-
-    return ST_CONTINUE;
-}
 #endif
+}
 
 static void
 rb_check_deadlock(rb_vm_t *vm)
 {
     int found = 0;
+    rb_thread_t *th;
 
     if (vm_living_thread_num(vm) > vm->sleeper) return;
     if (vm_living_thread_num(vm) < vm->sleeper) rb_bug("sleeper must not be more than vm_living_thread_num(vm)");
     if (patrol_thread && patrol_thread != GET_THREAD()) return;
 
-    rb_vm_living_threads_foreach(vm, check_deadlock_i, &found);
+    list_for_each(&vm->living_threads, th, vmlt_node) {
+	if (th->status != THREAD_STOPPED_FOREVER || RUBY_VM_INTERRUPTED(th)) {
+	    found = 1;
+	}
+	else if (th->locking_mutex) {
+	    rb_mutex_t *mutex;
+	    GetMutexPtr(th->locking_mutex, mutex);
+
+	    native_mutex_lock(&mutex->lock);
+	    if (mutex->th == th || (!mutex->th && mutex->cond_waiting)) {
+		found = 1;
+	    }
+	    native_mutex_unlock(&mutex->lock);
+	}
+	if (found)
+	    break;
+    }
 
     if (!found) {
 	VALUE argv[2];
 	argv[0] = rb_eFatal;
 	argv[1] = rb_str_new2("No live threads left. Deadlock?");
-#ifdef DEBUG_DEADLOCK_CHECK
-	printf("%d %d %p %p\n", vm_living_thread_num(vm), vm->sleeper, GET_THREAD(), vm->main_thread);
-	rb_vm_living_threads_foreach(vm, debug_i, 0);
-#endif
+	debug_deadlock_check(vm);
 	vm->sleeper--;
 	rb_threadptr_raise(vm->main_thread, 2, argv);
     }
Index: vm_trace.c
===================================================================
--- vm_trace.c	(revision 46194)
+++ vm_trace.c	(revision 46195)
@@ -212,17 +212,15 @@ rb_remove_event_hook_with_data(rb_event_ https://github.com/ruby/ruby/blob/trunk/vm_trace.c#L212
     return remove_event_hook(&GET_VM()->event_hooks, func, data);
 }
 
-static int
-clear_trace_func_i(rb_thread_t *th, void *unused)
-{
-    rb_threadptr_remove_event_hook(th, 0, Qundef);
-    return ST_CONTINUE;
-}
-
 void
 rb_clear_trace_func(void)
 {
-    rb_vm_living_threads_foreach(GET_VM(), clear_trace_func_i, 0);
+    rb_vm_t *vm = GET_VM();
+    rb_thread_t *th;
+
+    list_for_each(&vm->living_threads, th, vmlt_node) {
+	rb_threadptr_remove_event_hook(th, 0, Qundef);
+    }
     rb_remove_event_hook(0);
 }
 
Index: vm.c
===================================================================
--- vm.c	(revision 46194)
+++ vm.c	(revision 46195)
@@ -1685,13 +1685,6 @@ rb_vm_call_cfunc(VALUE recv, VALUE (*fun https://github.com/ruby/ruby/blob/trunk/vm.c#L1685
 
 /* vm */
 
-static int
-vm_mark_each_thread_func(rb_thread_t *th, void *dummy)
-{
-    rb_gc_mark(th->self);
-    return ST_CONTINUE;
-}
-
 void rb_vm_trace_mark_event_hooks(rb_hook_list_t *hooks);
 
 void
@@ -1703,7 +1696,11 @@ rb_vm_mark(void *ptr) https://github.com/ruby/ruby/blob/trunk/vm.c#L1696
     RUBY_GC_INFO("-------------------------------------------------\n");
     if (ptr) {
 	rb_vm_t *vm = ptr;
-	rb_vm_living_threads_foreach(vm, vm_mark_each_thread_func, 0);
+	rb_thread_t *th;
+
+	list_for_each(&vm->living_threads, th, vmlt_node) {
+	    rb_gc_mark(th->self);
+	}
 	RUBY_MARK_UNLESS_NULL(vm->thgroup_default);
 	RUBY_MARK_UNLESS_NULL(vm->mark_object_ary);
 	RUBY_MARK_UNLESS_NULL(vm->load_path);
@@ -3018,24 +3015,3 @@ vm_collect_usage_register(int reg, int i https://github.com/ruby/ruby/blob/trunk/vm.c#L3015
 	(*ruby_vm_collect_usage_func_register)(reg, isset);
 }
 #endif
-
-void
-rb_vm_living_threads_foreach(rb_vm_t *vm,
-			    int (*fn)(rb_thread_t *, void*), void *arg)
-{
-    rb_thread_t *cur = NULL, *next;
-    list_for_each_safe(&vm->living_threads, cur, next, vmlt_node) {
-	int rc = fn(cur, arg);
-	switch (rc) {
-	  case ST_CHECK:
-	  case ST_CONTINUE: break;
-	  case ST_STOP: return;
-	  case ST_DELETE: /* untested */
-	    rb_vm_living_threads_remove(vm, cur);
-	    xfree(cur);
-	    break;
-	  default:
-	    rb_bug("rb_vm_living_threads_foreach: unexpected: %d", rc);
-	}
-    }
-}

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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