[PATCH] osmo-sip-connector[master]: evpoll: Optimize layout of the pollfd array

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

Holger Freyther gerrit-no-reply at lists.osmocom.org
Wed Mar 8 09:32:53 UTC 2017


Hello Jenkins Builder,

I'd like you to reexamine a change.  Please visit

    https://gerrit.osmocom.org/1988

to look at the new patch set (#2).

evpoll: Optimize layout of the pollfd array

Avoid having too many empty entries in the pollfd entry but still have
O(n) when iterating over the result. Segment the array and skip entries
that were not added.

Change-Id: I1dfd9716a3620ad7932e8f46fd17536a6619fe0e
---
M src/evpoll.c
1 file changed, 28 insertions(+), 25 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/osmo-sip-connector refs/changes/88/1988/2

diff --git a/src/evpoll.c b/src/evpoll.c
index a646801..e8392db 100644
--- a/src/evpoll.c
+++ b/src/evpoll.c
@@ -52,23 +52,22 @@
 	return &ts;
 }
 
-#define MAYBE_CLEAR(fd, set, rflag)				\
+#define MAYBE_CLEAR(fd, pollfd, set, rflag)				\
 		if (FD_ISSET(fd, set))				\
-			if ((g_fds[fd].revents & rflag) == 0)	\
+			if (((pollfd)->revents & rflag) == 0)	\
 				FD_CLR(fd, set);
 
 int evpoll(struct pollfd *fds, nfds_t nfds, int timeout)
 {
 	struct timespec *ts, null_ts = { 0, 0} , poll_ts;
 	fd_set readset, writeset, exceptset;
-	int maxfd, i, rc, all_nfds;
+	int maxfd, i, j, rc, last_fd = 0, select_fds;
 
 	FD_ZERO(&readset);
 	FD_ZERO(&writeset);
 	FD_ZERO(&exceptset);
 
 	maxfd = osmo_fd_fill_fds(&readset, &writeset, &exceptset);
-	all_nfds = maxfd;
 
 	/* disable all fds */
 	for (i = 0; i < ARRAY_SIZE(g_fds); ++i) {
@@ -82,25 +81,27 @@
 			&& !FD_ISSET(i, &writeset) && !FD_ISSET(i, &exceptset))
 			continue;
 
-		g_fds[i].fd = i;
-		g_fds[i].events = 0;
+		g_fds[last_fd].fd = i;
+		g_fds[last_fd].events = 0;
 		if (FD_ISSET(i, &readset))
-			g_fds[i].events |= POLLIN;
+			g_fds[last_fd].events |= POLLIN;
 		if (FD_ISSET(i, &writeset))
-			g_fds[i].events |= POLLOUT;
+			g_fds[last_fd].events |= POLLOUT;
+		last_fd += 1;
 	}
+	select_fds = last_fd;
 
 	/* copy the remaining ones */
 	for (i = 0; i < nfds; ++i) {
-		if (fds[i].fd < 0)
-			continue;
-		if (fds[i].fd >= ARRAY_SIZE(g_fds)) {
-			LOGP(DAPP, LOGL_ERROR, "Can not poll fd=%d.\n", fds[i].fd);
+		if (fds[i].fd < 0) {
+			fds[i].revents = 0;
 			continue;
 		}
-		if (fds[i].fd > all_nfds)
-			all_nfds = fds[i].fd;
-		g_fds[fds[i].fd] = fds[i];
+		if (last_fd >= ARRAY_SIZE(g_fds)) {
+			LOGP(DAPP, LOGL_ERROR, "Can not add fd=%d.\n", fds[i].fd);
+			continue;
+		}
+		g_fds[last_fd++] = fds[i];
 	}
 
 	osmo_timers_check();
@@ -126,7 +127,7 @@
 			ts = &poll_ts;
 	}
 
-	rc = ppoll(g_fds, all_nfds + 1, ts, NULL);
+	rc = ppoll(g_fds, last_fd, ts, NULL);
 	if (rc < 0)
 		return 0;
 
@@ -134,21 +135,23 @@
 	osmo_timers_update();
 
 	/* call registered callback functions */
-	for (i = 0; i <= maxfd; ++i) {
-		MAYBE_CLEAR(i, &readset, POLLIN)
-		MAYBE_CLEAR(i, &writeset, POLLOUT)
-		MAYBE_CLEAR(i, &exceptset, POLLERR)
+	for (i = 0; i < select_fds; ++i) {
+		MAYBE_CLEAR(g_fds[i].fd, &g_fds[i], &readset, POLLIN)
+		MAYBE_CLEAR(g_fds[i].fd, &g_fds[i], &writeset, POLLOUT)
+		MAYBE_CLEAR(g_fds[i].fd, &g_fds[i], &exceptset, POLLERR)
 	}
 	osmo_fd_disp_fds(&readset, &writeset, &exceptset);
 
-	for (i = 0; i < nfds; ++i) {
-
-		if (fds[i].fd < 0) {
-			fds[i].revents = 0;
+	i = select_fds;
+	j = 0;
+	while (i < last_fd && j < nfds) {
+		/* g_fds might have skipped some fds.. so progress */
+		if (g_fds[i].fd != fds[j].fd) {
+			j += 1;
 			continue;
 		}
 
-		fds[i].revents  = g_fds[fds[i].fd].revents;
+		fds[j++].revents  = g_fds[i++].revents;
 	}
 
 	return rc;

-- 
To view, visit https://gerrit.osmocom.org/1988
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: newpatchset
Gerrit-Change-Id: I1dfd9716a3620ad7932e8f46fd17536a6619fe0e
Gerrit-PatchSet: 2
Gerrit-Project: osmo-sip-connector
Gerrit-Branch: master
Gerrit-Owner: Holger Freyther <holger at freyther.de>
Gerrit-Reviewer: Jenkins Builder



More information about the gerrit-log mailing list