[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
Tue Mar 7 14:12:34 UTC 2017


Review at  https://gerrit.osmocom.org/1988

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, 25 insertions(+), 22 deletions(-)


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

diff --git a/src/evpoll.c b/src/evpoll.c
index 291d0b5..3645f1f 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, osmo_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)
+		if (fds[i].fd < 0) {
+			fds[i].revents = 0;
 			continue;
+		}
 		if (fds[i].fd >= ARRAY_SIZE(g_fds)) {
 			LOGP(DAPP, LOGL_ERROR, "Can not poll fd=%d.\n", fds[i].fd);
 			continue;
 		}
-		if (fds[i].fd > all_nfds)
-			all_nfds = fds[i].fd;
-		g_fds[fds[i].fd] = fds[i];
+		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: newchange
Gerrit-Change-Id: I1dfd9716a3620ad7932e8f46fd17536a6619fe0e
Gerrit-PatchSet: 1
Gerrit-Project: osmo-sip-connector
Gerrit-Branch: master
Gerrit-Owner: Holger Freyther <holger at freyther.de>



More information about the gerrit-log mailing list