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

ruby-changes:51985

From: normal <ko1@a...>
Date: Mon, 6 Aug 2018 06:28:07 +0900 (JST)
Subject: [ruby-changes:51985] normal:r64200 (trunk): process.c (rb_waitpid): reduce sigwait_fd bouncing

normal	2018-08-06 06:27:14 +0900 (Mon, 06 Aug 2018)

  New Revision: 64200

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=64200

  Log:
    process.c (rb_waitpid): reduce sigwait_fd bouncing
    
    Once a thread has acquired sigwait_fd, hold onto it until
    waitpid is complete.  This prevents unnecessary migration
    and atomic operations.

  Modified files:
    trunk/process.c
Index: process.c
===================================================================
--- process.c	(revision 64199)
+++ process.c	(revision 64200)
@@ -928,6 +928,7 @@ struct waitpid_state { https://github.com/ruby/ruby/blob/trunk/process.c#L928
     int status;
     int options;
     int errnum;
+    int sigwait_fd;
 };
 
 void rb_native_mutex_lock(rb_nativethread_lock_t *);
@@ -1075,19 +1076,18 @@ ruby_waitpid_locked(rb_vm_t *vm, rb_pid_ https://github.com/ruby/ruby/blob/trunk/process.c#L1076
         if (w.ret == -1) w.errnum = errno;
     }
     else {
-        int sigwait_fd;
-
         w.ec = 0;
+        w.sigwait_fd = -1;
         list_add(w.pid > 0 ? &vm->waiting_pids : &vm->waiting_grps, &w.wnode);
         do {
-            sigwait_fd = rb_sigwait_fd_get(0);
+            if (w.sigwait_fd < 0)
+                w.sigwait_fd = rb_sigwait_fd_get(0);
 
-            if (sigwait_fd >= 0) {
+            if (w.sigwait_fd >= 0) {
                 w.cond = 0;
                 rb_native_mutex_unlock(&vm->waitpid_lock);
-                rb_sigwait_sleep(0, sigwait_fd, sigwait_sleep_time());
+                rb_sigwait_sleep(0, w.sigwait_fd, sigwait_sleep_time());
                 rb_native_mutex_lock(&vm->waitpid_lock);
-                rb_sigwait_fd_put(0, sigwait_fd);
             }
             else {
                 w.cond = cond;
@@ -1097,8 +1097,10 @@ ruby_waitpid_locked(rb_vm_t *vm, rb_pid_ https://github.com/ruby/ruby/blob/trunk/process.c#L1097
         list_del(&w.wnode);
 
         /* we're done, maybe other waitpid callers are not: */
-        if (sigwait_fd >= 0)
+        if (w.sigwait_fd >= 0) {
+            rb_sigwait_fd_put(0, w.sigwait_fd);
             sigwait_fd_migrate_sleeper(vm);
+        }
     }
     if (status) {
         *status = w.status;
@@ -1124,7 +1126,6 @@ waitpid_nogvl(void *x) https://github.com/ruby/ruby/blob/trunk/process.c#L1126
 {
     struct waitpid_state *w = x;
     rb_thread_t *th = rb_ec_thread_ptr(w->ec);
-    int sigwait_fd = -1;
 
     rb_native_mutex_lock(&th->interrupt_lock);
     /*
@@ -1132,16 +1133,17 @@ waitpid_nogvl(void *x) https://github.com/ruby/ruby/blob/trunk/process.c#L1133
      * by the time we enter this.  And we may also be interrupted.
      */
     if (!w->ret && !RUBY_VM_INTERRUPTED_ANY(w->ec)) {
-        sigwait_fd = rb_sigwait_fd_get(th);
-        if (sigwait_fd >= 0) {
+        if (w->sigwait_fd < 0)
+            w->sigwait_fd = rb_sigwait_fd_get(th);
+
+        if (w->sigwait_fd >= 0) {
             rb_nativethread_cond_t *cond = w->cond;
 
             w->cond = 0;
             rb_native_mutex_unlock(&th->interrupt_lock);
-            rb_sigwait_sleep(th, sigwait_fd, sigwait_sleep_time());
+            rb_sigwait_sleep(th, w->sigwait_fd, sigwait_sleep_time());
             rb_native_mutex_lock(&th->interrupt_lock);
             w->cond = cond;
-            rb_sigwait_fd_put(th, sigwait_fd);
         }
         else {
             if (!w->cond)
@@ -1167,8 +1169,6 @@ waitpid_nogvl(void *x) https://github.com/ruby/ruby/blob/trunk/process.c#L1169
 
     rb_native_mutex_unlock(&th->interrupt_lock);
 
-    if (sigwait_fd >= 0)
-        rb_sigwait_fd_migrate(th->vm);
     return 0;
 }
 
@@ -1201,6 +1201,10 @@ waitpid_cleanup(VALUE x) https://github.com/ruby/ruby/blob/trunk/process.c#L1201
     if (w->cond)
         rb_sleep_cond_put(w->cond);
 
+    if (w->sigwait_fd >= 0) {
+        rb_sigwait_fd_put(rb_ec_thread_ptr(w->ec), w->sigwait_fd);
+        rb_sigwait_fd_migrate(rb_ec_vm_ptr(w->ec));
+    }
     return Qfalse;
 }
 
@@ -1227,6 +1231,7 @@ waitpid_wait(struct waitpid_state *w) https://github.com/ruby/ruby/blob/trunk/process.c#L1231
     }
     else {
         w->cond = rb_sleep_cond_get(w->ec);
+        w->sigwait_fd = -1;
         /* order matters, favor specified PIDs rather than -1 or 0 */
         list_add(w->pid > 0 ? &vm->waiting_pids : &vm->waiting_grps, &w->wnode);
     }

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

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