Project

General

Profile

Misc #15011 ยป 0001-thread_pthread.c-use-eventfd-instead-of-pipe-on-Linu.patch

normalperson (Eric Wong), 08/20/2018 06:17 AM

View differences:

configure.ac
AC_CHECK_HEADERS(setjmpex.h)
AC_CHECK_HEADERS(stdalign.h)
AC_CHECK_HEADERS(sys/attr.h)
AC_CHECK_HEADERS(sys/eventfd.h)
AC_CHECK_HEADERS(sys/fcntl.h)
AC_CHECK_HEADERS(sys/file.h)
AC_CHECK_HEADERS(sys/id.h)
......
AC_CHECK_FUNCS(dup3)
AC_CHECK_FUNCS(eaccess)
AC_CHECK_FUNCS(endgrent)
AC_CHECK_FUNCS(eventfd)
AC_CHECK_FUNCS(fchmod)
AC_CHECK_FUNCS(fchown)
AC_CHECK_FUNCS(fcntl)
thread.c
# define BUSY_WAIT_SIGNALS (0)
#endif
#ifndef USE_EVENTFD
# define USE_EVENTFD (0)
#endif
#if THREAD_DEBUG
static int debug_mutex_initialized = 1;
static rb_nativethread_lock_t debug_mutex;
......
static int
consume_communication_pipe(int fd)
{
#define CCP_READ_BUFF_SIZE 1024
#if USE_EVENTFD
uint64_t buff[1];
#else
/* buffer can be shared because no one refers to them. */
static char buff[CCP_READ_BUFF_SIZE];
static char buff[1024];
#endif
ssize_t result;
int ret = FALSE; /* for rb_sigwait_sleep */
......
result = read(fd, buff, sizeof(buff));
if (result > 0) {
ret = TRUE;
if (result < (ssize_t)sizeof(buff)) {
if (USE_EVENTFD || result < (ssize_t)sizeof(buff)) {
return ret;
}
}
thread_pthread.c
#include <time.h>
#include <signal.h>
#if defined(HAVE_SYS_EVENTFD_H) && defined(HAVE_EVENTFD)
# define USE_EVENTFD (1)
# include <sys/eventfd.h>
#else
# define USE_EVENTFD (0)
#endif
#if defined(SIGVTALRM) && !defined(__CYGWIN__)
# define USE_UBF_LIST 1
#endif
......
static void
rb_thread_wakeup_timer_thread_fd(int fd)
{
#if USE_EVENTFD
const uint64_t buff = 1;
#else
const char buff = '!';
#endif
ssize_t result;
/* already opened */
if (fd >= 0) {
static const char buff[1] = {'!'};
retry:
if ((result = write(fd, buff, 1)) <= 0) {
if ((result = write(fd, &buff, sizeof(buff))) <= 0) {
int e = errno;
switch (e) {
case EINTR: goto retry;
......
}
}
#define CLOSE_INVALIDATE(expr) \
close_invalidate(&expr,"close_invalidate: "#expr)
#define CLOSE_INVALIDATE_PAIR(expr) \
close_invalidate_pair(expr,"close_invalidate: "#expr)
static void
close_invalidate(int *fdp, const char *msg)
{
......
}
}
static void
close_invalidate_pair(int fds[2], const char *msg)
{
if (USE_EVENTFD && fds[0] == fds[1]) {
close_invalidate(&fds[0], msg);
fds[1] = -1;
}
else {
close_invalidate(&fds[0], msg);
close_invalidate(&fds[1], msg);
}
}
static void
set_nonblock(int fd)
{
......
return 0;
}
/*
* Don't bother with eventfd on ancient Linux 2.6.22..2.6.26 which were
* missing EFD_* flags, they can fall back to pipe
*/
#if USE_EVENTFD && defined(EFD_NONBLOCK) && defined(EFD_CLOEXEC)
pipes[0] = pipes[1] = eventfd(0, EFD_NONBLOCK|EFD_CLOEXEC);
if (pipes[0] >= 0) {
rb_update_max_fd(pipes[0]);
return 0;
}
#endif
err = rb_cloexec_pipe(pipes);
if (err != 0) {
rb_warn("pipe creation failed for timer: %s, scheduling broken",
......
ubf_timer_invalidate(void)
{
#if UBF_TIMER == UBF_TIMER_PTHREAD
CLOSE_INVALIDATE(timer_pthread.low[0]);
CLOSE_INVALIDATE(timer_pthread.low[1]);
CLOSE_INVALIDATE_PAIR(timer_pthread.low);
#endif
}
......
rb_pid_t owner = signal_self_pipe.owner_process;
if (owner && owner != current) {
CLOSE_INVALIDATE(signal_self_pipe.normal[0]);
CLOSE_INVALIDATE(signal_self_pipe.normal[1]);
CLOSE_INVALIDATE_PAIR(signal_self_pipe.normal);
ubf_timer_invalidate();
}
-
    (1-1/1)