From 734931d84fd54f65fd8b2658829191ce101b10bb Mon Sep 17 00:00:00 2001 From: Přemysl Janouch Date: Wed, 24 Sep 2014 00:54:38 +0200 Subject: Fix the hotspot Valgrind seems to be quite happy with it now. --- utils.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/utils.c b/utils.c index 800c31a..d5df179 100644 --- a/utils.c +++ b/utils.c @@ -1161,22 +1161,29 @@ poller_set (struct poller *self, struct poller_fd *fd) modifying ? EPOLL_CTL_MOD : EPOLL_CTL_ADD, fd->fd, &event) != -1); } -// FIXME: this is by far the slowest function in the whole program +static int +poller_compare_fds (const void *ax, const void *bx) +{ + const struct epoll_event *ay = ax, *by = bx; + struct poller_fd *a = ay->data.ptr, *b = by->data.ptr; + return a->fd - b->fd; +} + static void poller_remove_from_dispatch (struct poller *self, const struct poller_fd *fd) { if (!self->dispatch_total) return; - int i; - for (i = self->dispatch_next; i < self->dispatch_total; i++) - if (self->revents[i].data.ptr == fd) - break; - if (i == self->dispatch_total) + struct epoll_event key = { .data.ptr = (void *) fd }, *fd_event; + if (!(fd_event = bsearch (&key, self->revents, + self->dispatch_total, sizeof *self->revents, poller_compare_fds))) return; - if (i != --self->dispatch_total) - self->revents[i] = self->revents[self->dispatch_total]; + ssize_t i = fd_event - self->revents; + if (i < self->dispatch_next) + self->dispatch_next--; + memmove (fd_event, fd_event + 1, (--self->dispatch_total - i) * sizeof key); } static void @@ -1219,6 +1226,9 @@ poller_run (struct poller *self) poller_timers_dispatch (&self->timers); poller_idle_dispatch (self->idle); + // Sort them by file descriptor number for binary search + qsort (self->revents, n_fds, sizeof *self->revents, poller_compare_fds); + while (self->dispatch_next < self->dispatch_total) { struct epoll_event *revents = self->revents + self->dispatch_next; -- cgit v1.2.3-70-g09d2