ruby-changes:19410
From: kosaki <ko1@a...>
Date: Fri, 6 May 2011 23:59:18 +0900 (JST)
Subject: [ruby-changes:19410] Ruby:r31450 (trunk): * thread.c (rb_wait_for_single_fd): use ppoll() instead of poll()
kosaki 2011-05-06 23:58:38 +0900 (Fri, 06 May 2011) New Revision: 31450 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=31450 Log: * thread.c (rb_wait_for_single_fd): use ppoll() instead of poll() if possible. based on a patch from Eric Wong. [ruby-core:36003]. Modified files: trunk/ChangeLog trunk/configure.in trunk/thread.c Index: configure.in =================================================================== --- configure.in (revision 31449) +++ configure.in (revision 31450) @@ -1310,7 +1310,7 @@ dlopen sigprocmask sigaction sigsetjmp _setjmp _longjmp\ setsid telldir seekdir fchmod cosh sinh tanh log2 round\ setuid setgid daemon select_large_fdset setenv unsetenv\ - mktime timegm gmtime_r clock_gettime gettimeofday poll\ + mktime timegm gmtime_r clock_gettime gettimeofday poll ppoll\ pread sendfile shutdown sigaltstack dl_iterate_phdr) AC_CACHE_CHECK(for unsetenv returns a value, rb_cv_unsetenv_return_value, Index: ChangeLog =================================================================== --- ChangeLog (revision 31449) +++ ChangeLog (revision 31450) @@ -1,3 +1,8 @@ +Fri May 6 23:29:47 2011 KOSAKI Motohiro <kosaki.motohiro@g...> + + * thread.c (rb_wait_for_single_fd): use ppoll() instead of poll() + if possible. based on a patch from Eric Wong. [ruby-core:36003]. + Fri May 6 23:13:43 2011 KOSAKI Motohiro <kosaki.motohiro@g...> * configure.in: remove nanosleep check. we no longer use it. Index: thread.c =================================================================== --- thread.c (revision 31449) +++ thread.c (revision 31450) @@ -2715,12 +2715,41 @@ #ifdef USE_POLL - /* The same with linux kernel. TODO: make platform independent definition. */ #define POLLIN_SET (POLLRDNORM | POLLRDBAND | POLLIN | POLLHUP | POLLERR) #define POLLOUT_SET (POLLWRBAND | POLLWRNORM | POLLOUT | POLLERR) #define POLLEX_SET (POLLPRI) +#define TIMET_MAX (~(time_t)0 <= 0 ? (time_t)((~(unsigned_time_t)0) >> 1) : (time_t)(~(unsigned_time_t)0)) +#define TIMET_MIN (~(time_t)0 <= 0 ? (time_t)(((unsigned_time_t)1) << (sizeof(time_t) * CHAR_BIT - 1)) : (time_t)0) + +#ifndef HAVE_PPOLL +/* TODO: don't ignore sigmask */ +int ppoll(struct pollfd *fds, nfds_t nfds, + const struct timespec *ts, const sigset_t *sigmask) +{ + int timeout_ms; + + if (ts) { + int tmp, tmp2; + + if (ts->tv_sec > TIMET_MAX/1000) + timeout_ms = -1; + else { + tmp = ts->tv_sec * 1000; + tmp2 = tv->tv_nsec / (1000 * 1000); + if (TIMET_MAX - tmp < tmp2) + timeout_ms = -1; + else + timeout_ms = tmp + tmp2; + } + } else + timeout = -1; + + return poll(fds, nfds, timeout_ms); +} +#endif + /* * returns a mask of events */ @@ -2729,17 +2758,25 @@ { struct pollfd fds; int result, lerrno; - double start; - int timeout = tv ? tv->tv_sec * 1000 + (tv->tv_usec + 500) / 1000 : -1; + double limit = 0; + struct timespec ts; + struct timespec *timeout = NULL; + if (tv) { + ts.tv_sec = tv->tv_sec; + ts.tv_nsec = tv->tv_usec * 1000; + limit = timeofday(); + limit += (double)tv->tv_sec + (double)tv->tv_usec * 1e-6; + timeout = &ts; + } + fds.fd = fd; fds.events = (short)events; retry: lerrno = 0; - start = timeofday(); BLOCKING_REGION({ - result = poll(&fds, 1, timeout); + result = ppoll(&fds, 1, timeout, NULL); if (result < 0) lerrno = errno; }, ubf_select, GET_THREAD()); @@ -2750,10 +2787,15 @@ #ifdef ERESTART case ERESTART: #endif - if (timeout > 0) { - timeout -= (timeofday() - start) * 1000; - if (timeout < 0) - timeout = 0; + if (timeout) { + double d = limit - timeofday(); + + ts.tv_sec = (long)d; + ts.tv_nsec = (long)((d - (double)ts.tv_sec) * 1e9); + if (ts.tv_sec < 0) + ts.tv_sec = 0; + if (ts.tv_nsec < 0) + ts.tv_nsec = 0; } goto retry; } -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/