[PATCH] linux_kevent_wait: avoid pselect() if timeout is exactly zero

56 views
Skip to first unread message

Eric Wong

unread,
Dec 10, 2012, 8:27:50 PM12/10/12
to libk...@googlegroups.com
While processing a long-running task, an application may use
kevent() or epoll_wait() with a zero timeout to check if there
are pending events in the ready list. Checking the ready list
in a non-blocking fashion allows a thread-constrained
application to decide whether or not to continue processing the
long-running task or to switch to processing the newly-ready
event.

epoll_wait() in Linux is also optimized for the timeout=0 case
since 2.6.39 (commit f4d93ad74c18143abd3067ca3c8ffba7d00addf4).
---
This patch is downloadable from:

http://bogomips.org/libkqueue.git/patch?id=05a433b014

src/linux/platform.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/linux/platform.c b/src/linux/platform.c
index 8f8ace2..cb118da 100644
--- a/src/linux/platform.c
+++ b/src/linux/platform.c
@@ -121,7 +121,7 @@ linux_kevent_wait(
int timeout, nret;

/* Use pselect() if the timeout value is less than one millisecond. */
- if (ts != NULL && ts->tv_sec == 0 && ts->tv_nsec < 1000000) {
+ if (ts != NULL && ts->tv_sec == 0 && ts->tv_nsec > 0 && ts->tv_nsec < 1000000) {
nret = linux_kevent_wait_hires(kq, ts);
if (nret <= 0)
return (nret);
--
Eric Wong

Eric Wong

unread,
Dec 10, 2012, 8:30:50 PM12/10/12
to libk...@googlegroups.com
Some applications may create the kqueue/epoll descriptor after
creating (many) other descriptors. ppoll() provides consistent
performance and memory usage for high-numbered file descriptors
in this case.

ppoll() has been available since Linux 2.6.16, however we
already depend on eventfd() which came in Linux 2.6.22.
---
Downloadable from: http://bogomips.org/libkqueue.git/patch?id=222e95c6b3

src/linux/platform.c | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/src/linux/platform.c b/src/linux/platform.c
index cb118da..82830be 100644
--- a/src/linux/platform.c
+++ b/src/linux/platform.c
@@ -14,6 +14,8 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

+# define _GNU_SOURCE
+# include <poll.h>
#include "../common/private.h"

//XXX-FIXME TEMP
@@ -90,16 +92,15 @@ linux_kevent_wait_hires(
struct kqueue *kq,
const struct timespec *timeout)
{
- fd_set fds;
int n;
- int epfd;
+ struct pollfd fds;

dbg_printf("waiting for events (timeout=%ld sec %ld nsec)",
timeout->tv_sec, timeout->tv_nsec);
- epfd = kqueue_epfd(kq);
- FD_ZERO(&fds);
- FD_SET(epfd, &fds);
- n = pselect(epfd + 1, &fds, NULL , NULL, timeout, NULL);
+ fds.fd = kqueue_epfd(kq);
+ fds.events = POLLIN;
+
+ n = ppoll(&fds, 1, timeout, NULL);
if (n < 0) {
if (errno == EINTR) {
dbg_puts("signal caught");
@@ -120,13 +121,13 @@ linux_kevent_wait(
{
int timeout, nret;

- /* Use pselect() if the timeout value is less than one millisecond. */
+ /* Use ppoll() if the timeout value is less than one millisecond. */
if (ts != NULL && ts->tv_sec == 0 && ts->tv_nsec > 0 && ts->tv_nsec < 1000000) {
nret = linux_kevent_wait_hires(kq, ts);
if (nret <= 0)
return (nret);

- /* pselect() told us epoll_wait() should have ready events */
+ /* ppoll() told us epoll_wait() should have ready events */
timeout = 0;
} else {
/* Convert timeout to the format used by epoll_wait() */
--
Eric Wong

Mark Heily

unread,
Dec 24, 2012, 12:16:30 PM12/24/12
to libkqueue
Committed as r609, thanks!


--
Eric Wong

--
You received this message because you are subscribed to the Google Groups "libkqueue" group.
To post to this group, send email to libk...@googlegroups.com.
To unsubscribe from this group, send email to libkqueue+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/libkqueue?hl=en.


Mark Heily

unread,
Dec 24, 2012, 6:37:01 PM12/24/12
to libkqueue
This was committed in r610. However, on Android, the ppoll() function is not implemented in the C library, so it will fallback to using pselect() on this platform.

Thanks,
 
- Mark


--
Eric Wong

Eric Wong

unread,
Dec 24, 2012, 6:54:57 PM12/24/12
to libk...@googlegroups.com
Mark Heily <ma...@heily.com> wrote:
> This was committed in r610. However, on Android, the ppoll() function is
> not implemented in the C library, so it will fallback to using pselect() on
> this platform.

Thanks. It'd probably be good to get Android to support ppoll() so we
can eventually drop the pselect() fallback. I don't have any experience
(nor much interest) in Android, though.

Mark Heily

unread,
Dec 24, 2012, 7:09:53 PM12/24/12
to libkqueue
This will only happen if ppoll is "needed by the platform" in the opinion of the Android maintainers. Here's a discussion I had about a similar issue:


The kernel supports ppoll, so it should be possible to implement it invoking syscall() and providing the numeric syscall ID.  It's ugly, so I'm content to wait and see if it gets added to a future version of the Android platfrom.


Reply all
Reply to author
Forward
0 new messages