diff options
| author | Přemysl Janouch <p.janouch@gmail.com> | 2014-09-24 00:54:38 +0200 | 
|---|---|---|
| committer | Přemysl Janouch <p.janouch@gmail.com> | 2014-09-24 01:02:09 +0200 | 
| commit | 734931d84fd54f65fd8b2658829191ce101b10bb (patch) | |
| tree | 5e0b9365cce3ef33b180ef055f6ab9d29e29f6af | |
| parent | bdb3b9b9593260b5224a4de09fdb46d8748eb2ab (diff) | |
| download | ponymap-734931d84fd54f65fd8b2658829191ce101b10bb.tar.gz ponymap-734931d84fd54f65fd8b2658829191ce101b10bb.tar.xz ponymap-734931d84fd54f65fd8b2658829191ce101b10bb.zip | |
Fix the hotspot
Valgrind seems to be quite happy with it now.
| -rw-r--r-- | utils.c | 26 | 
1 files changed, 18 insertions, 8 deletions
| @@ -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; | 
