DEV: tcploop: add optional support for epoll
When -e is passed, epoll is used instead of poll. The FD is added
then removed around the call to epoll_wait() so that we don't need
to track it. The only purpose is to compare events reported by each
syscall.
diff --git a/dev/tcploop/tcploop.c b/dev/tcploop/tcploop.c
index e875258..d8e9f0f 100644
--- a/dev/tcploop/tcploop.c
+++ b/dev/tcploop/tcploop.c
@@ -33,6 +33,11 @@
#include <sys/time.h>
#include <sys/ioctl.h>
#include <sys/wait.h>
+
+#ifdef __linux__
+#include <sys/epoll.h>
+#endif
+
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
@@ -77,6 +82,7 @@
static struct timeval start_time;
static int showtime;
static int verbose;
+static int use_epoll;
static int pid;
static int sock_type = SOCK_STREAM;
static int sock_proto = IPPROTO_TCP;
@@ -105,6 +111,7 @@
" -v : verbose\n"
" -u : use UDP instead of TCP (limited)\n"
" -t|-tt|-ttt : show time (msec / relative / absolute)\n"
+ " -e : use epoll instead of poll on Linux\n"
"actions :\n"
" A[<count>] : Accepts <count> incoming sockets and closes count-1\n"
" Note: fd=accept(fd)\n"
@@ -313,6 +320,31 @@
struct pollfd pollfd;
int ret;
+#ifdef __linux__
+ while (use_epoll) {
+ struct epoll_event evt;
+ static int epoll_fd = -1;
+
+ if (epoll_fd == -1)
+ epoll_fd = epoll_create(1024);
+ if (epoll_fd == -1)
+ break;
+ evt.events = ((events & POLLIN) ? EPOLLIN : 0) |
+ ((events & POLLOUT) ? EPOLLOUT : 0) |
+ ((events & POLLRDHUP) ? EPOLLRDHUP : 0);
+ evt.data.fd = fd;
+ epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &evt);
+
+ do {
+ ret = epoll_wait(epoll_fd, &evt, 1, ms);
+ } while (ret == -1 && errno == EINTR);
+
+ evt.data.fd = fd;
+ epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, &evt);
+ return ret;
+ }
+#endif
+
do {
pollfd.fd = fd;
pollfd.events = events;
@@ -795,6 +827,8 @@
showtime += 2;
else if (strcmp(argv[0], "-ttt") == 0)
showtime += 3;
+ else if (strcmp(argv[0], "-e") == 0)
+ use_epoll = 1;
else if (strcmp(argv[0], "-v") == 0)
verbose ++;
else if (strcmp(argv[0], "-u") == 0) {