summaryrefslogtreecommitdiff
path: root/thread_pthread.c
diff options
context:
space:
mode:
authornormal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-07-05 03:02:33 (GMT)
committernormal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-07-05 03:02:33 (GMT)
commit44fc3d08eb3cb52df5bdd91a0d9723718654b349 (patch)
tree0034ca54aa0fbb3d6f4c46f2a0405ea20e3d23b9 /thread_pthread.c
parentb3799b93c20c00865c1bd5885890291c0874f029 (diff)
unrevert r63852 but keep SIGCHLD path disabled for win32
Reading win32/win32.c waitpid implementation, maybe waitpid(-1, ...) on that platform will never conflict with mjit use of waitpid. In any case, I've added WAITPID_USE_SIGCHLD macro to vm_core.h so it can be easy for Linux/BSD users to test (hopefully!) win32-compatible code. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63855 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'thread_pthread.c')
-rw-r--r--thread_pthread.c47
1 files changed, 40 insertions, 7 deletions
diff --git a/thread_pthread.c b/thread_pthread.c
index 8a48255..722ce44 100644
--- a/thread_pthread.c
+++ b/thread_pthread.c
@@ -1369,7 +1369,7 @@ setup_communication_pipe(void)
* @pre the calling context is in the timer thread.
*/
static inline void
-timer_thread_sleep(rb_global_vm_lock_t* gvl)
+timer_thread_sleep(rb_vm_t *vm)
{
int result;
int need_polling;
@@ -1382,7 +1382,15 @@ timer_thread_sleep(rb_global_vm_lock_t* gvl)
need_polling = !ubf_threads_empty();
- if (gvl->waiting > 0 || need_polling) {
+ if (SIGCHLD_LOSSY && !need_polling) {
+ rb_native_mutex_lock(&vm->waitpid_lock);
+ if (!list_empty(&vm->waiting_pids) || !list_empty(&vm->waiting_grps)) {
+ need_polling = 1;
+ }
+ rb_native_mutex_unlock(&vm->waitpid_lock);
+ }
+
+ if (vm->gvl.waiting > 0 || need_polling) {
/* polling (TIME_QUANTUM_USEC usec) */
result = poll(pollfds, 1, TIME_QUANTUM_USEC/1000);
}
@@ -1421,7 +1429,7 @@ static rb_nativethread_lock_t timer_thread_lock;
static rb_nativethread_cond_t timer_thread_cond;
static inline void
-timer_thread_sleep(rb_global_vm_lock_t* unused)
+timer_thread_sleep(rb_vm_t *unused)
{
struct timespec ts;
ts.tv_sec = 0;
@@ -1485,7 +1493,14 @@ native_set_another_thread_name(rb_nativethread_id_t thread_id, VALUE name)
static void *
thread_timer(void *p)
{
- rb_global_vm_lock_t *gvl = (rb_global_vm_lock_t *)p;
+ rb_vm_t *vm = p;
+#ifdef HAVE_PTHREAD_SIGMASK /* mainly to enable SIGCHLD */
+ {
+ sigset_t mask;
+ sigemptyset(&mask);
+ pthread_sigmask(SIG_SETMASK, &mask, NULL);
+ }
+#endif
if (TT_DEBUG) WRITE_CONST(2, "start timer thread\n");
@@ -1507,7 +1522,7 @@ thread_timer(void *p)
if (TT_DEBUG) WRITE_CONST(2, "tick\n");
/* wait */
- timer_thread_sleep(gvl);
+ timer_thread_sleep(vm);
}
#if USE_SLEEPY_TIMER_THREAD
CLOSE_INVALIDATE(normal[0]);
@@ -1579,7 +1594,7 @@ rb_thread_create_timer_thread(void)
if (timer_thread.created) {
rb_bug("rb_thread_create_timer_thread: Timer thread was already created\n");
}
- err = pthread_create(&timer_thread.id, &attr, thread_timer, &vm->gvl);
+ err = pthread_create(&timer_thread.id, &attr, thread_timer, vm);
pthread_attr_destroy(&attr);
if (err == EINVAL) {
@@ -1590,7 +1605,7 @@ rb_thread_create_timer_thread(void)
* default stack size is enough for them:
*/
stack_size = 0;
- err = pthread_create(&timer_thread.id, NULL, thread_timer, &vm->gvl);
+ err = pthread_create(&timer_thread.id, NULL, thread_timer, vm);
}
if (err != 0) {
rb_warn("pthread_create failed for timer: %s, scheduling broken",
@@ -1771,4 +1786,22 @@ rb_thread_create_mjit_thread(void (*child_hook)(void), void (*worker_func)(void)
return ret;
}
+#define USE_NATIVE_SLEEP_COND (1)
+
+#if USE_NATIVE_SLEEP_COND
+rb_nativethread_cond_t *
+rb_sleep_cond_get(const rb_execution_context_t *ec)
+{
+ rb_thread_t *th = rb_ec_thread_ptr(ec);
+
+ return &th->native_thread_data.sleep_cond;
+}
+
+void
+rb_sleep_cond_put(rb_nativethread_cond_t *cond)
+{
+ /* no-op */
+}
+#endif /* USE_NATIVE_SLEEP_COND */
+
#endif /* THREAD_SYSTEM_DEPENDENT_IMPLEMENTATION */