1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Copyright (c) Ulrich Drepper <drepper@redhat.com>
4 * Copyright (c) International Business Machines  Corp., 2009
5 * Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
6 */
7
8/*\
9 * [Description]
10 *
11 * This test verifies that eventfd2 semaphore-like support is properly working.
12 */
13
14#include <fcntl.h>
15#include <stdlib.h>
16#include <sys/eventfd.h>
17#include "tst_test.h"
18#include "eventfd2.h"
19
20static void xsem_wait(int fd)
21{
22	u_int64_t cntr;
23
24	SAFE_READ(0, fd, &cntr, sizeof(cntr));
25}
26
27static void xsem_post(int fd, int count)
28{
29	u_int64_t cntr = count;
30
31	SAFE_WRITE(0, fd, &cntr, sizeof(cntr));
32}
33
34static void sem_player(int fd1, int fd2)
35{
36	pid_t pid = getpid();
37
38	tst_res(TINFO, "[%u] posting 1 on fd=%d", pid, fd1);
39	xsem_post(fd1, 1);
40
41	tst_res(TINFO, "[%u] waiting on fd=%d", pid, fd2);
42	xsem_wait(fd2);
43
44	tst_res(TINFO, "[%u] posting 5 on fd=%d", pid, fd1);
45	xsem_post(fd1, 5);
46
47	tst_res(TINFO, "[%u] waiting 5 times on fd=%d", pid, fd2);
48	xsem_wait(fd2);
49	xsem_wait(fd2);
50	xsem_wait(fd2);
51	xsem_wait(fd2);
52	xsem_wait(fd2);
53
54	tst_res(TPASS, "[%u] received all events", pid);
55}
56
57static void run(void)
58{
59	pid_t cpid_poster, cpid_waiter;
60	int fd1, fd2;
61
62	fd1 = eventfd2(0, EFD_SEMAPHORE);
63	fd2 = eventfd2(0, EFD_SEMAPHORE);
64
65	cpid_poster = SAFE_FORK();
66	if (!cpid_poster) {
67		sem_player(fd1, fd2);
68		exit(0);
69	}
70
71	cpid_waiter = SAFE_FORK();
72	if (!cpid_waiter) {
73		sem_player(fd2, fd1);
74		exit(0);
75	}
76}
77
78static struct tst_test test = {
79	.test_all = run,
80	.forks_child = 1,
81};
82