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/