aboutsummaryrefslogtreecommitdiffstats
path: root/process.c
diff options
context:
space:
mode:
authornormal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-08-05 21:27:14 +0000
committernormal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-08-05 21:27:14 +0000
commit1ff3857320041d494fa0036fdc87361016b2b2fe (patch)
tree8b5e446169639417a4b454b1553dbd0a6afd1521 /process.c
parent309165a581c4c1300b5d4ec9131caa2e8d826462 (diff)
downloadruby-1ff3857320041d494fa0036fdc87361016b2b2fe.tar.gz
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. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64200 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'process.c')
-rw-r--r--process.c33
1 files changed, 19 insertions, 14 deletions
diff --git a/process.c b/process.c
index 177fac62d5..11ecc59b0f 100644
--- a/process.c
+++ b/process.c
@@ -928,6 +928,7 @@ struct waitpid_state {
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_t pid, int *status, int options,
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_t pid, int *status, int options,
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)
{
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)
* 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)
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)
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)
}
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);
}