Feature #14851 ยป 0001-thread_pthread.c-remove-non-sleepy-timer-thread-impl.patch
thread_pthread.c | ||
---|---|---|
/* The timer thread sleeps while only one Ruby thread is running. */
|
||
# define USE_SLEEPY_TIMER_THREAD 1
|
||
#else
|
||
# define USE_SLEEPY_TIMER_THREAD 0
|
||
# error pthreads system lacks poll+fcntl? \
|
||
please let us know at ruby-core@ruby-lang.org
|
||
#endif
|
||
static void
|
||
... | ... | |
return err;
|
||
}
|
||
#if USE_SLEEPY_TIMER_THREAD
|
||
static void
|
||
native_thread_join(pthread_t th)
|
||
{
|
||
... | ... | |
rb_raise(rb_eThreadError, "native_thread_join() failed (%d)", err);
|
||
}
|
||
}
|
||
#endif
|
||
#if USE_NATIVE_THREAD_PRIORITY
|
||
... | ... | |
*/
|
||
#define TIME_QUANTUM_USEC (100 * 1000)
|
||
#if USE_SLEEPY_TIMER_THREAD
|
||
static struct {
|
||
/*
|
||
* Read end of each pipe is closed inside timer thread for shutdown
|
||
... | ... | |
}
|
||
}
|
||
#else /* USE_SLEEPY_TIMER_THREAD */
|
||
# define PER_NANO 1000000000
|
||
void rb_thread_wakeup_timer_thread(void) {}
|
||
static void rb_thread_wakeup_timer_thread_low(void) {}
|
||
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)
|
||
{
|
||
struct timespec ts;
|
||
ts.tv_sec = 0;
|
||
ts.tv_nsec = TIME_QUANTUM_USEC * 1000;
|
||
ts = native_cond_timeout(&timer_thread_cond, ts);
|
||
native_cond_timedwait(&timer_thread_cond, &timer_thread_lock, &ts);
|
||
}
|
||
#endif /* USE_SLEEPY_TIMER_THREAD */
|
||
#if !defined(SET_CURRENT_THREAD_NAME) && defined(__linux__) && defined(PR_SET_NAME)
|
||
# define SET_CURRENT_THREAD_NAME(name) prctl(PR_SET_NAME, name)
|
||
#endif
|
||
... | ... | |
#ifdef SET_CURRENT_THREAD_NAME
|
||
SET_CURRENT_THREAD_NAME("ruby-timer-thr");
|
||
#endif
|
||
#if !USE_SLEEPY_TIMER_THREAD
|
||
rb_native_mutex_initialize(&timer_thread_lock);
|
||
rb_native_cond_initialize(&timer_thread_cond);
|
||
rb_native_mutex_lock(&timer_thread_lock);
|
||
#endif
|
||
while (system_working > 0) {
|
||
/* timer function */
|
||
... | ... | |
/* wait */
|
||
timer_thread_sleep(gvl);
|
||
}
|
||
#if USE_SLEEPY_TIMER_THREAD
|
||
CLOSE_INVALIDATE(normal[0]);
|
||
CLOSE_INVALIDATE(low[0]);
|
||
#else
|
||
rb_native_mutex_unlock(&timer_thread_lock);
|
||
rb_native_cond_destroy(&timer_thread_cond);
|
||
rb_native_mutex_destroy(&timer_thread_lock);
|
||
#endif
|
||
if (TT_DEBUG) WRITE_CONST(2, "finish timer thread\n");
|
||
return NULL;
|
||
... | ... | |
}
|
||
# endif
|
||
#if USE_SLEEPY_TIMER_THREAD
|
||
err = setup_communication_pipe();
|
||
if (err != 0) {
|
||
rb_warn("pipe creation failed for timer: %s, scheduling broken",
|
||
strerror(err));
|
||
return;
|
||
}
|
||
#endif /* USE_SLEEPY_TIMER_THREAD */
|
||
/* create timer thread */
|
||
if (timer_thread.created) {
|
||
... | ... | |
rb_warn("timer thread stack size: system default");
|
||
}
|
||
VM_ASSERT(err == 0);
|
||
#if USE_SLEEPY_TIMER_THREAD
|
||
CLOSE_INVALIDATE(normal[0]);
|
||
CLOSE_INVALIDATE(normal[1]);
|
||
CLOSE_INVALIDATE(low[0]);
|
||
CLOSE_INVALIDATE(low[1]);
|
||
#endif
|
||
return;
|
||
}
|
||
#if USE_SLEEPY_TIMER_THREAD
|
||
/* validate pipe on this process */
|
||
timer_thread_pipe.owner_process = getpid();
|
||
#endif
|
||
timer_thread.created = 1;
|
||
}
|
||
}
|
||
... | ... | |
stopped = --system_working <= 0;
|
||
if (TT_DEBUG) fprintf(stderr, "stop timer thread\n");
|
||
#if USE_SLEEPY_TIMER_THREAD
|
||
if (stopped) {
|
||
/* prevent wakeups from signal handler ASAP */
|
||
timer_thread_pipe.owner_process = 0;
|
||
... | ... | |
if (TT_DEBUG) fprintf(stderr, "joined timer thread\n");
|
||
timer_thread.created = 0;
|
||
}
|
||
#endif
|
||
return stopped;
|
||
}
|
||
... | ... | |
int
|
||
rb_reserved_fd_p(int fd)
|
||
{
|
||
#if USE_SLEEPY_TIMER_THREAD
|
||
if ((fd == timer_thread_pipe.normal[0] ||
|
||
fd == timer_thread_pipe.normal[1] ||
|
||
fd == timer_thread_pipe.low[0] ||
|
||
... | ... | |
else {
|
||
return 0;
|
||
}
|
||
#else
|
||
return 0;
|
||
#endif
|
||
}
|
||
rb_nativethread_id_t
|
||
-
|