x11perf -noop with 200 xlogos connected is slightly faster with ports:
before after Operation
-- -
1840.0 1920.0 (1.04) X protocol NoOperation
Signed-off-by: Peter Harris
---
include/meson.build | 1 +
os/ospoll.c | 128 +---
2 files changed, 122 insertions(+), 7 deletions(-)
diff --git a/include/meson.build b/include/meson.build
index e0ebee258..8eec9ce36 100644
--- a/include/meson.build
+++ b/include/meson.build
@@ -126,6 +126,7 @@ conf_data.set('HAVE_MMAP', cc.has_function('mmap'))
conf_data.set('HAVE_POLL', cc.has_function('poll'))
conf_data.set('HAVE_POLLSET_CREATE', cc.has_function('pollset_create'))
conf_data.set('HAVE_POSIX_FALLOCATE', cc.has_function('posix_fallocate'))
+conf_data.set('HAVE_PORT_CREATE', cc.has_function('port_create'))
conf_data.set('HAVE_REALLOCARRAY', cc.has_function('reallocarray',
dependencies: libbsd_dep))
conf_data.set('HAVE_SETEUID', cc.has_function('seteuid'))
conf_data.set('HAVE_SETITIMER', cc.has_function('setitimer'))
diff --git a/os/ospoll.c b/os/ospoll.c
index 4a59a5e6b..db9e73811 100644
--- a/os/ospoll.c
+++ b/os/ospoll.c
@@ -38,6 +38,12 @@
#define HAVE_OSPOLL 1
#endif
+#if !HAVE_OSPOLL && defined(HAVE_PORT_CREATE)
+#include
+#define PORT1
+#define HAVE_OSPOLL 1
+#endif
+
#if !HAVE_OSPOLL && defined(HAVE_EPOLL_CREATE1)
#include
#define EPOLL 1
@@ -71,7 +77,7 @@ struct ospoll {
#endif
-#if EPOLL
+#if EPOLL || PORT
#include
/* epoll-based implementation */
@@ -128,7 +134,7 @@ ospoll_find(struct ospoll *ospoll, int fd)
while (lo <= hi) {
int m = (lo + hi) >> 1;
-#if EPOLL
+#if EPOLL || PORT
int t = ospoll->fds[m]->fd;
#endif
#if POLL || POLLSET
@@ -145,7 +151,7 @@ ospoll_find(struct ospoll *ospoll, int fd)
return -(lo + 1);
}
-#if EPOLL
+#if EPOLL || PORT
static void
ospoll_clean_deleted(struct ospoll *ospoll)
{
@@ -205,6 +211,17 @@ ospoll_create(void)
}
return ospoll;
#endif
+#if PORT
+struct ospoll *ospoll = calloc(1, sizeof (struct ospoll));
+
+ospoll->epoll_fd = port_create();
+if (ospoll->epoll_fd < 0) {
+free (ospoll);
+return NULL;
+}
+xorg_list_init(>deleted);
+return ospoll;
+#endif
#if EPOLL
struct ospoll *ospoll = calloc(1, sizeof (struct ospoll));
@@ -232,7 +249,7 @@ ospoll_destroy(struct ospoll *ospoll)
free(ospoll);
}
#endif
-#if EPOLL
+#if EPOLL || PORT
if (ospoll) {
assert (ospoll->num == 0);
close(ospoll->epoll_fd);
@@ -282,6 +299,41 @@ ospoll_add(struct ospoll *ospoll, int fd,
ospoll->fds[pos].callback = callback;
ospoll->fds[pos].data = data;
#endif
+#if PORT
+struct ospollfd *osfd;
+
+if (pos < 0) {
+osfd = calloc(1, sizeof (struct ospollfd));
+if (!osfd)
+return FALSE;
+
+if (ospoll->num >= ospoll->size) {
+struct ospollfd **new_fds;
+int new_size = ospoll->size ? ospoll->size * 2 : MAXCLIENTS * 2;
+
+new_fds = reallocarray(ospoll->fds, new_size, sizeof
(ospoll->fds[0]));
+if (!new_fds) {
+free (osfd);
+return FALSE;
+}
+ospoll->fds = new_fds;
+ospoll->size = new_size;
+}
+
+osfd->fd = fd;
+osfd->xevents = 0;
+
+pos = -pos - 1;
+array_insert(ospoll->fds, ospoll->num, sizeof (ospoll->fds[0]), pos);
+ospoll->fds[pos] = osfd;
+ospoll->num++;
+} else {
+osfd = ospoll->fds[pos];
+}
+osfd->data = data;
+osfd->callback = callback;
+osfd->trigger = trigger;
+#endif
#if EPOLL
struct ospollfd *osfd;
@@ -378,6 +430,16 @@ ospoll_remove(struct ospoll *ospoll, int fd)
array_delete(ospoll->fds, ospoll->num, sizeof (ospoll->fds[0]), pos);
ospoll->num--;
#endif
+#if PORT
+struct ospollfd *osfd = ospoll->fds[pos];
+port_dissociate(ospoll->epoll_fd, PORT_SOURCE_FD, fd);
+
+array_delete(ospoll->fds, ospoll->num, sizeof (ospoll->fds[0]), pos);
+ospoll->num--;
+osfd->callback = NULL;
+osfd->data = NULL;
+xorg_list_add(>deleted, >deleted);
+#endif
#if EPOLL
struct ospollfd *osfd = ospoll->fds[pos];
struct epoll_event ev;
@@ -400,6 +462,19 @@ ospoll_remove(struct ospoll *ospoll, int fd)
}
}
+#if PORT
+static void
+epoll_mod(struct ospoll *ospoll, struct ospollfd *osfd)
+{
+int events = 0;
+if (osfd->xevents & X_NOTIFY_READ)
+events |= EPOLLIN;
+if (osfd->xevents & X_NOTIFY_WRITE)
+events |= EPOLLOUT;
+port_associate(ospool->epoll_fd, PORT_SOURCE_FD, osfd->fd, events, osfd);
+}
+#endif
+
#if EPOLL
static void
epoll_mod(struct ospoll *ospoll, struct ospollfd *osfd)
@@ -436,7 +511,7 @@ ospoll_listen(struct ospoll *ospoll, int