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
|
||
|
-
|
||