Index: mca/event/libevent2013/configure.m4 =================================================================== --- mca/event/libevent2013/configure.m4 (revision 26274) +++ mca/event/libevent2013/configure.m4 (working copy) @@ -52,6 +52,12 @@ if test "$enable_event_poll" = "no"; then event_args="$event_args --disable-poll" fi + + AC_ARG_ENABLE(event-mosix-ppoll, + AC_HELP_STRING([--disable-event-mosix-ppoll], [disable MOSIX ppoll support])) + if test "$enable_event_mosix_ppoll" = "no"; then + event_args="$event_args --disable-mosix-ppoll" + fi AC_ARG_ENABLE(event-devpoll, AC_HELP_STRING([--disable-event-devpoll], [disable devpoll support])) Index: mca/event/libevent2013/libevent2013_module.c =================================================================== --- mca/event/libevent2013/libevent2013_module.c (revision 26274) +++ mca/event/libevent2013/libevent2013_module.c (working copy) @@ -65,6 +65,9 @@ #if defined(_EVENT_HAVE_SELECT) && _EVENT_HAVE_SELECT extern const struct eventop selectops; #endif +#if defined(_EVENT_HAVE_MOSIX_PPOLL) && _EVENT_HAVE_MOSIX_PPOLL +extern const struct eventop mosix_ppollops; +#endif #if defined(_EVENT_HAVE_POLL) && _EVENT_HAVE_POLL extern const struct eventop pollops; #endif @@ -95,6 +98,9 @@ #if defined(_EVENT_HAVE_DEVPOLL) && _EVENT_HAVE_DEVPOLL &devpollops, #endif +#if defined(_EVENT_HAVE_MOSIX_PPOLL) && _EVENT_HAVE_MOSIX_PPOLL + &mosix_ppollops, +#endif #if defined(_EVENT_HAVE_POLL) && _EVENT_HAVE_POLL &pollops, #endif @@ -194,9 +200,13 @@ #ifdef __WINDOWS__ "win32", #else +#ifdef _EVENT_HAVE_MOSIX_PPOLL + "mosix_ppoll", +#else "poll", #endif #endif +#endif &event_module_include); if (dumpit) { Index: mca/event/libevent2013/libevent/configure.in =================================================================== --- mca/event/libevent2013/libevent/configure.in (revision 26274) +++ mca/event/libevent2013/libevent/configure.in (working copy) @@ -453,9 +453,18 @@ needsignal=yes fi fi -AM_CONDITIONAL(POLL_BACKEND, [test "x$havepoll" = "xyes" -a "$enable_poll" != "no"]) + +AM_CONDITIONAL(MOSIX_PPOLL_BACKEND, [test "x$havepoll" = "xyes" -a "$enable_mosix_ppoll" != "no" && test -n "/proc/mosix/mosip"]) +AC_MSG_CHECKING([for mosix_ppoll support]) +AS_IF([test "$enable_mosix_ppoll" != "no" && test "x$havepoll" = "xyes"], + [AC_DEFINE(HAVE_MOSIX_PPOLL, 1, [Have MOSIX ppoll support]) + AC_MSG_RESULT([yes])], + [AC_DEFINE(HAVE_MOSIX_PPOLL, 0, [No MOSIX ppoll support]) + AC_MSG_RESULT([no])]) + +AM_CONDITIONAL(POLL_BACKEND, [test "x$havepoll" = "xyes" -a "$enable_poll" != "no" -a "$enable_mosix_poll" == "no"]) AC_MSG_CHECKING([for poll support]) -AS_IF([test "$enable_poll" != "no" && test "x$havepoll" = "xyes"], +AS_IF([test "$enable_poll" != "no" && test "$enable_mosix_poll" == "no" && test "x$havepoll" = "xyes"], [AC_DEFINE(HAVE_POLL, 1, [Have poll support]) AC_MSG_RESULT([yes])], [AC_DEFINE(HAVE_POLL, 0, [No poll support]) Index: mca/event/libevent2013/libevent/mosix_ppoll.c =================================================================== --- mca/event/libevent2013/libevent/mosix_ppoll.c (revision 0) +++ mca/event/libevent2013/libevent/mosix_ppoll.c (revision 0) @@ -0,0 +1,384 @@ +/* $OpenBSD: mosix_ppoll.c,v 1.2 2002/06/25 15:50:15 mickey Exp $ */ + +/* + * Copyright 2000-2007 Niels Provos + * Copyright 2007-2010 Niels Provos and Nick Mathewson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "event2/event-config.h" + +#include +#ifdef _EVENT_HAVE_SYS_TIME_H +#include +#endif +#ifdef _EVENT_HAVE_SYS_STAT_H +#include +#endif +#ifdef _EVENT_HAVE_FCNTL_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "event-internal.h" +#include "evsignal-internal.h" +#include "log-internal.h" +#include "evmap-internal.h" +#include "event2/thread.h" +#include "evthread-internal.h" + +#define MOSIX_PPOLL_MBOX_FD_LOWER_LIMIT (1000000000) +#define MOSIX_PPOLL_MBOX_DEFAULT_FLAGS (71) +#define MOSIX_PPOLL_MBOX_SIGIO_FLAGS (71 | 16) +#define MOSIX_PPOLL_MBOX_OPEN_FILE_PATH "/proc/mosix/mybox" + +struct pollidx { + int idxplus1; +}; + +struct mosix_ppollop { + int event_count; /* Highest number alloc */ + int nfds; /* Highest number used */ + int realloc_copy; /* True iff we must realloc + * event_set_copy */ + + struct pollfd *event_set; + struct pollfd *event_set_copy; + + int mosix_fd; /* High FD of a MOSIX mailbox or 0. */ + sigset_t sigio; /* SIGIO-only sigmask for ppoll interruption */ +}; + +static void *mosix_ppoll_init(struct event_base *); +static int mosix_ppoll_add(struct event_base *, int, short old, short events, void *_idx); +static int mosix_ppoll_del(struct event_base *, int, short old, short events, void *_idx); +static int mosix_ppoll_dispatch(struct event_base *, struct timeval *); +static void mosix_ppoll_dealloc(struct event_base *); + +const struct eventop mosix_ppollops = { + "mosix_ppoll", + mosix_ppoll_init, + mosix_ppoll_add, + mosix_ppoll_del, + mosix_ppoll_dispatch, + mosix_ppoll_dealloc, + 0, /* doesn't need_reinit */ + EV_FEATURE_FDS, + sizeof(struct pollidx), +}; + +/* This dummy handler is only used to allow SIGIO interrupt the poll() syscall */ +static void mosix_ppoll_dummy_sigio_handler() {} + +static void * +mosix_ppoll_init(struct event_base *base) +{ + struct mosix_ppollop *mosix_ppollop; + + if (!(mosix_ppollop = mm_calloc(1, sizeof(struct mosix_ppollop)))) + return (NULL); + + evsig_init(base); + /* TODO: Setup the sigid_t for ppoll */ + //evsig_add(base, SIGIO, 0,0, NULL); + + return (mosix_ppollop); +} + +#ifdef CHECK_INVARIANTS +static void +mosix_ppoll_check_ok(struct mosix_ppollop *pop) +{ + int i, idx; + struct event *ev; + + for (i = 0; i < pop->fd_count; ++i) { + idx = pop->idxplus1_by_fd[i]-1; + if (idx < 0) + continue; + EVUTIL_ASSERT(pop->event_set[idx].fd == i); + } + for (i = 0; i < pop->nfds; ++i) { + struct pollfd *pfd = &pop->event_set[i]; + EVUTIL_ASSERT(pop->idxplus1_by_fd[pfd->fd] == i+1); + } +} +#else +#define mosix_ppoll_check_ok(pop) +#endif + +static void mosix_ppoll_check_mosix_dicom(struct event_base *base, int fd) +{ + if (read(((struct mosix_ppollop*)(base->evbase))->mosix_fd, NULL, -1)) { + evmap_io_active(base, fd, EV_READ); + } +} + +static int +mosix_ppoll_dispatch(struct event_base *base, struct timeval *tv) +{ + int res, i, j, nfds; + long msec = -1; + struct mosix_ppollop *pop = base->evbase; + struct pollfd *event_set; + + mosix_ppoll_check_ok(pop); + + nfds = pop->nfds; + +#ifndef _EVENT_DISABLE_THREAD_SUPPORT + if (base->th_base_lock) { + /* If we're using this backend in a multithreaded setting, + * then we need to work on a copy of event_set, so that we can + * let other threads modify the main event_set while we're + * polling. If we're not multithreaded, then we'll skip the + * copy step here to save memory and time. */ + if (pop->realloc_copy) { + struct pollfd *tmp = mm_realloc(pop->event_set_copy, + pop->event_count * sizeof(struct pollfd)); + if (tmp == NULL) { + event_warn("realloc"); + return -1; + } + pop->event_set_copy = tmp; + pop->realloc_copy = 0; + } + memcpy(pop->event_set_copy, pop->event_set, + sizeof(struct pollfd)*nfds); + event_set = pop->event_set_copy; + } else { + event_set = pop->event_set; + } +#else + event_set = pop->event_set; +#endif + + if (0 < pop->mosix_fd) { + mosix_ppoll_check_mosix_dicom(base, pop->mosix_fd); + pop->mosix_fd = open(MOSIX_PPOLL_MBOX_OPEN_FILE_PATH, O_CREAT, + MOSIX_PPOLL_MBOX_SIGIO_FLAGS); + } + + /* TODO: remove */ + if (tv != NULL) { + msec = evutil_tv_to_msec(tv); + if (msec < 0 || msec > INT_MAX) + msec = INT_MAX; + } + + EVBASE_RELEASE_LOCK(base, th_base_lock); + + printf("OUR PPOLL!\n"); + res = poll(event_set, nfds, msec); /* TODO: tv, sigmap_t*/ + + EVBASE_ACQUIRE_LOCK(base, th_base_lock); + if (0 < pop->mosix_fd) { + pop->mosix_fd = open(MOSIX_PPOLL_MBOX_OPEN_FILE_PATH, O_CREAT, + MOSIX_PPOLL_MBOX_SIGIO_FLAGS); + } + if (res == -1) { + if (errno != EINTR) { + event_warn("poll"); + return (-1); + } + + if (0 < pop->mosix_fd) { + mosix_ppoll_check_mosix_dicom(base, pop->mosix_fd); + } + return (0); + } + + event_debug(("%s: poll reports %d", __func__, res)); + + if (res == 0 || nfds == 0) + return (0); + + i = random() % nfds; + for (j = 0; j < nfds; j++) { + int what; + if (++i == nfds) + i = 0; + what = event_set[i].revents; + if (!what) + continue; + + res = 0; + + /* If the file gets closed notify */ + if (what & (POLLHUP|POLLERR)) + what |= POLLIN|POLLOUT; + if (what & POLLIN) + res |= EV_READ; + if (what & POLLOUT) + res |= EV_WRITE; + if (res == 0) + continue; + + evmap_io_active(base, event_set[i].fd, res); + } + + return (0); +} + +static int +mosix_ppoll_add(struct event_base *base, int fd, short old, short events, void *_idx) +{ + struct mosix_ppollop *pop = base->evbase; + struct pollfd *pfd = NULL; + struct pollidx *idx = _idx; + int i; + + EVUTIL_ASSERT((events & EV_SIGNAL) == 0); + if (!(events & (EV_READ|EV_WRITE))) + return (0); + + if (MOSIX_PPOLL_MBOX_FD_LOWER_LIMIT < fd) { + pop->mosix_fd = fd; + return (0); + } + + mosix_ppoll_check_ok(pop); + if (pop->nfds + 1 >= pop->event_count) { + struct pollfd *tmp_event_set; + int tmp_event_count; + + if (pop->event_count < 32) + tmp_event_count = 32; + else + tmp_event_count = pop->event_count * 2; + + /* We need more file descriptors */ + tmp_event_set = mm_realloc(pop->event_set, + tmp_event_count * sizeof(struct pollfd)); + if (tmp_event_set == NULL) { + event_warn("realloc"); + return (-1); + } + pop->event_set = tmp_event_set; + + pop->event_count = tmp_event_count; + pop->realloc_copy = 1; + } + + i = idx->idxplus1 - 1; + + if (i >= 0) { + pfd = &pop->event_set[i]; + } else { + i = pop->nfds++; + pfd = &pop->event_set[i]; + pfd->events = 0; + pfd->fd = fd; + idx->idxplus1 = i + 1; + } + + pfd->revents = 0; + if (events & EV_WRITE) + pfd->events |= POLLOUT; + if (events & EV_READ) + pfd->events |= POLLIN; + mosix_ppoll_check_ok(pop); + + return (0); +} + +/* + * Nothing to be done here. + */ + +static int +mosix_ppoll_del(struct event_base *base, int fd, short old, short events, void *_idx) +{ + struct mosix_ppollop *pop = base->evbase; + struct pollfd *pfd = NULL; + struct pollidx *idx = _idx; + int i; + + EVUTIL_ASSERT((events & EV_SIGNAL) == 0); + if (!(events & (EV_READ|EV_WRITE))) + return (0); + + if (pop->mosix_fd == fd) { + pop->mosix_fd = 0; + return (0); + } + + mosix_ppoll_check_ok(pop); + i = idx->idxplus1 - 1; + if (i < 0) + return (-1); + + /* Do we still want to read or write? */ + pfd = &pop->event_set[i]; + if (events & EV_READ) + pfd->events &= ~POLLIN; + if (events & EV_WRITE) + pfd->events &= ~POLLOUT; + mosix_ppoll_check_ok(pop); + if (pfd->events) + /* Another event cares about that fd. */ + return (0); + + /* Okay, so we aren't interested in that fd anymore. */ + idx->idxplus1 = 0; + + --pop->nfds; + if (i != pop->nfds) { + /* + * Shift the last pollfd down into the now-unoccupied + * position. + */ + memcpy(&pop->event_set[i], &pop->event_set[pop->nfds], + sizeof(struct pollfd)); + idx = evmap_io_get_fdinfo(&base->io, pop->event_set[i].fd); + EVUTIL_ASSERT(idx); + EVUTIL_ASSERT(idx->idxplus1 == pop->nfds + 1); + idx->idxplus1 = i + 1; + } + + mosix_ppoll_check_ok(pop); + return (0); +} + +static void +mosix_ppoll_dealloc(struct event_base *base) +{ + struct mosix_ppollop *pop = base->evbase; + + evsig_dealloc(base); + if (pop->event_set) + mm_free(pop->event_set); + if (pop->event_set_copy) + mm_free(pop->event_set_copy); + + memset(pop, 0, sizeof(struct mosix_ppollop)); + mm_free(pop); +} Index: mca/event/libevent2013/libevent/event.c =================================================================== --- mca/event/libevent2013/libevent/event.c (revision 26274) +++ mca/event/libevent2013/libevent/event.c (working copy) @@ -81,6 +81,9 @@ #if defined(_EVENT_HAVE_SELECT) && _EVENT_HAVE_SELECT extern const struct eventop selectops; #endif +#if defined(_EVENT_HAVE_MOSIX_PPOLL) && _EVENT_HAVE_MOSIX_PPOLL +extern const struct eventop mosix_ppollops; +#endif #if defined(_EVENT_HAVE_POLL) && _EVENT_HAVE_POLL extern const struct eventop pollops; #endif @@ -111,6 +114,9 @@ #if defined(_EVENT_HAVE_DEVPOLL) && _EVENT_HAVE_DEVPOLL &devpollops, #endif +#if defined(_EVENT_HAVE_MOSIX_PPOLL) && _EVENT_HAVE_MOSIX_PPOLL + &mosix_ppollops, +#endif #if defined(_EVENT_HAVE_POLL) && _EVENT_HAVE_POLL &pollops, #endif Index: mca/event/libevent2013/libevent/Makefile.am =================================================================== --- mca/event/libevent2013/libevent/Makefile.am (revision 26274) +++ mca/event/libevent2013/libevent/Makefile.am (working copy) @@ -137,6 +137,9 @@ if POLL_BACKEND SYS_SRC += poll.c endif +if MOSIX_PPOLL_BACKEND +SYS_SRC += mosix_ppoll.c +endif if DEVPOLL_BACKEND SYS_SRC += devpoll.c endif