[LTP] [PATCH v2 4/5] syscalls: Add epoll_wait15
Cyril Hrubis
chrubis@suse.cz
Wed Jul 15 14:36:11 CEST 2026
A test that all epoll instances are woken up on a single event.
Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
---
runtest/syscalls | 1 +
.../kernel/syscalls/epoll_wait/.gitignore | 1 +
.../kernel/syscalls/epoll_wait/epoll_wait15.c | 102 ++++++++++++++++++
3 files changed, 104 insertions(+)
create mode 100644 testcases/kernel/syscalls/epoll_wait/epoll_wait15.c
diff --git a/runtest/syscalls b/runtest/syscalls
index 7c7e4b6f6..af04b430e 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -204,6 +204,7 @@ epoll_wait11 epoll_wait11
epoll_wait12 epoll_wait12
epoll_wait13 epoll_wait13
epoll_wait14 epoll_wait14
+epoll_wait15 epoll_wait15
epoll_pwait01 epoll_pwait01
epoll_pwait02 epoll_pwait02
diff --git a/testcases/kernel/syscalls/epoll_wait/.gitignore b/testcases/kernel/syscalls/epoll_wait/.gitignore
index fadaf4faa..5ba917bdb 100644
--- a/testcases/kernel/syscalls/epoll_wait/.gitignore
+++ b/testcases/kernel/syscalls/epoll_wait/.gitignore
@@ -12,3 +12,4 @@ epoll_wait11
epoll_wait12
epoll_wait13
epoll_wait14
+epoll_wait15
diff --git a/testcases/kernel/syscalls/epoll_wait/epoll_wait15.c b/testcases/kernel/syscalls/epoll_wait/epoll_wait15.c
new file mode 100644
index 000000000..5460a4ab5
--- /dev/null
+++ b/testcases/kernel/syscalls/epoll_wait/epoll_wait15.c
@@ -0,0 +1,102 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Cyril Hrubis <chrubis@suse.cz>
+ */
+
+/*\
+ * Verify that a single event on a file descriptor monitored by several epoll
+ * instances wakes all of the waiters blocked in :manpage:`epoll_wait(2)`.
+ *
+ * This is the default (non-EPOLLEXCLUSIVE) behavior and serves as the contrast
+ * to the thundering-herd avoidance tested in epoll_wait16.
+ */
+
+#include <sys/epoll.h>
+#include <sys/mman.h>
+
+#include "tst_test.h"
+#include "tst_epoll.h"
+#include "tst_atomic.h"
+
+#define NWAITERS 8
+
+static int fds[2] = {-1, -1};
+static pid_t pids[NWAITERS];
+static tst_atomic_t *woken;
+
+static void setup(void)
+{
+ woken = SAFE_MMAP(NULL, sizeof(*woken), PROT_READ | PROT_WRITE,
+ MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+}
+
+static void cleanup(void)
+{
+ if (fds[0] != -1) {
+ SAFE_CLOSE(fds[0]);
+ SAFE_CLOSE(fds[1]);
+ }
+
+ if (woken)
+ SAFE_MUNMAP(woken, sizeof(*woken));
+}
+
+static void child(void)
+{
+ int efd;
+ struct epoll_event ev = {.events = EPOLLIN | EPOLLET};
+
+ efd = SAFE_EPOLL_CREATE1(0);
+ SAFE_EPOLL_CTL(efd, EPOLL_CTL_ADD, fds[0], &ev);
+
+ TST_CHECKPOINT_WAKE(0);
+
+ if (epoll_wait(efd, &ev, 1, 2000) == 1)
+ tst_atomic_add_return(1, woken);
+
+ SAFE_CLOSE(efd);
+ exit(0);
+}
+
+static void run(void)
+{
+ int i, nwoken;
+
+ tst_atomic_store(0, woken);
+
+ SAFE_PIPE(fds);
+
+ for (i = 0; i < NWAITERS; i++) {
+ pids[i] = SAFE_FORK();
+ if (!pids[i])
+ child();
+
+ TST_CHECKPOINT_WAIT(0);
+ }
+
+ for (i = 0; i < NWAITERS; i++)
+ TST_PROCESS_STATE_WAIT(pids[i], 'S', 0);
+
+ SAFE_WRITE(SAFE_WRITE_ALL, fds[1], "x", 1);
+
+ tst_reap_children();
+
+ nwoken = tst_atomic_load(woken);
+
+ if (nwoken == NWAITERS)
+ tst_res(TPASS, "single event woke all %d waiters", NWAITERS);
+ else
+ tst_res(TFAIL, "single event woke %d of %d waiters",
+ nwoken, NWAITERS);
+
+ SAFE_CLOSE(fds[0]);
+ SAFE_CLOSE(fds[1]);
+}
+
+static struct tst_test test = {
+ .setup = setup,
+ .cleanup = cleanup,
+ .test_all = run,
+ .forks_child = 1,
+ .needs_checkpoints = 1,
+};
--
2.54.0
More information about the ltp
mailing list