From: Anton Ivanov <[email protected]> If we are not obtaining any useful information out of the poll(), such as is a fd busy or not, we do not need to do a poll() if an immediate_wake() has been requested.
This cuts out all the pollfd hash additions, forming the poll arguments and the actual poll() after a call to poll_immediate_wake() Signed-off-by: Anton Ivanov <[email protected]> --- lib/poll-loop.c | 73 +++++++++++++++++++++++++++++++++---------------- lib/timeval.c | 11 +++++++- 2 files changed, 60 insertions(+), 24 deletions(-) diff --git a/lib/poll-loop.c b/lib/poll-loop.c index 4e751ff2c..4ab11de50 100644 --- a/lib/poll-loop.c +++ b/lib/poll-loop.c @@ -107,6 +107,16 @@ poll_create_node(int fd, HANDLE wevent, short int events, const char *where) COVERAGE_INC(poll_create_node); + if (loop->timeout_when <= 0) { + /* There was a previous request to bail out of this poll loop. + * 0 - explicit time_poll_wait() + * LLONG_MIN - timeout computation resulted in a request + * to wake immediately. + * There is no point to engage in yack shaving a poll hmap. + */ + return; + } + /* Both 'fd' and 'wevent' cannot be set. */ ovs_assert(!fd != !wevent); @@ -181,8 +191,21 @@ poll_wevent_wait_at(HANDLE wevent, const char *where) void poll_timer_wait_at(long long int msec, const char *where) { - long long int now = time_msec(); + long long int now; long long int when; + struct poll_loop *loop = poll_loop(); + + /* We have an outstanding request for an immediate wake - + * either explicit (from poll_immediate_wake()) or as a + * result of a previous timeout calculation which gave + * a negative timeout. + * No point trying to recalculate the timeout. + */ + if (loop->timeout_when <= 0) { + return; + } + + now = time_msec(); if (msec <= 0) { /* Wake up immediately. */ @@ -320,10 +343,10 @@ poll_block(void) { struct poll_loop *loop = poll_loop(); struct poll_node *node; - struct pollfd *pollfds; + struct pollfd *pollfds = NULL; HANDLE *wevents = NULL; int elapsed; - int retval; + int retval = 0; int i; /* Register fatal signal events before actually doing any real work for @@ -335,34 +358,38 @@ poll_block(void) } timewarp_run(); - pollfds = xmalloc(hmap_count(&loop->poll_nodes) * sizeof *pollfds); + if (loop->timeout_when > 0) { + pollfds = xmalloc(hmap_count(&loop->poll_nodes) * sizeof *pollfds); #ifdef _WIN32 - wevents = xmalloc(hmap_count(&loop->poll_nodes) * sizeof *wevents); + wevents = xmalloc(hmap_count(&loop->poll_nodes) * sizeof *wevents); #endif - /* Populate with all the fds and events. */ - i = 0; - HMAP_FOR_EACH (node, hmap_node, &loop->poll_nodes) { - pollfds[i] = node->pollfd; + /* Populate with all the fds and events. */ + i = 0; + HMAP_FOR_EACH (node, hmap_node, &loop->poll_nodes) { + pollfds[i] = node->pollfd; #ifdef _WIN32 - wevents[i] = node->wevent; - if (node->pollfd.fd && node->wevent) { - short int wsa_events = 0; - if (node->pollfd.events & POLLIN) { - wsa_events |= FD_READ | FD_ACCEPT | FD_CLOSE; - } - if (node->pollfd.events & POLLOUT) { - wsa_events |= FD_WRITE | FD_CONNECT | FD_CLOSE; + wevents[i] = node->wevent; + if (node->pollfd.fd && node->wevent) { + short int wsa_events = 0; + if (node->pollfd.events & POLLIN) { + wsa_events |= FD_READ | FD_ACCEPT | FD_CLOSE; + } + if (node->pollfd.events & POLLOUT) { + wsa_events |= FD_WRITE | FD_CONNECT | FD_CLOSE; + } + WSAEventSelect(node->pollfd.fd, node->wevent, wsa_events); } - WSAEventSelect(node->pollfd.fd, node->wevent, wsa_events); - } #endif - i++; - } + i++; + } - retval = time_poll(pollfds, hmap_count(&loop->poll_nodes), wevents, - loop->timeout_when, &elapsed); + retval = time_poll(pollfds, hmap_count(&loop->poll_nodes), wevents, + loop->timeout_when, &elapsed); + } else { + retval = time_poll(NULL, 0, NULL, loop->timeout_when, &elapsed); + } if (retval < 0) { static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5); VLOG_ERR_RL(&rl, "poll: %s", ovs_strerror(-retval)); diff --git a/lib/timeval.c b/lib/timeval.c index 193c7bab1..42d8c258c 100644 --- a/lib/timeval.c +++ b/lib/timeval.c @@ -323,7 +323,13 @@ time_poll(struct pollfd *pollfds, int n_pollfds, HANDLE *handles OVS_UNUSED, } #ifndef _WIN32 - retval = poll(pollfds, n_pollfds, time_left); + /* n_pollfds is 0 only if we are doing a immediate_wake + * shortcut. Otherwise there is at least one fd for + * the signals pipe. + */ + if (n_pollfds != 0) { + retval = poll(pollfds, n_pollfds, time_left); + } if (retval < 0) { retval = -errno; } @@ -331,6 +337,9 @@ time_poll(struct pollfd *pollfds, int n_pollfds, HANDLE *handles OVS_UNUSED, if (n_pollfds > MAXIMUM_WAIT_OBJECTS) { VLOG_ERR("Cannot handle more than maximum wait objects\n"); } else if (n_pollfds != 0) { + /* If we are doing an immediate_wake shortcut n_pollfds is + * zero, so we skip the actual call. + */ retval = WaitForMultipleObjects(n_pollfds, handles, FALSE, time_left); } -- 2.20.1 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
