[PATCH v2 4/5] syscalls: Add epoll_wait15
Cyril Hrubis <[email protected]>
| Newsgroups | gmane.linux.ltp |
|---|---|
| Message-ID | <[email protected]> |
A test that all epoll instances are woken up on a single event. Signed-off-by: Cyril Hrubis <[email protected]> --- 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 <[email protected]> + */ + +/*\ + * 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 -- Mailing list info: https://lists.linux.it/listinfo/ltp