1*d7159b37SAndy Fiddaman /*
2*d7159b37SAndy Fiddaman * This file and its contents are supplied under the terms of the
3*d7159b37SAndy Fiddaman * Common Development and Distribution License ("CDDL"), version 1.0.
4*d7159b37SAndy Fiddaman * You may only use this file in accordance with the terms of version
5*d7159b37SAndy Fiddaman * 1.0 of the CDDL.
6*d7159b37SAndy Fiddaman *
7*d7159b37SAndy Fiddaman * A full copy of the text of the CDDL should have accompanied this
8*d7159b37SAndy Fiddaman * source. A copy of the CDDL is also available via the Internet at
9*d7159b37SAndy Fiddaman * http://www.illumos.org/license/CDDL.
10*d7159b37SAndy Fiddaman */
11*d7159b37SAndy Fiddaman
12*d7159b37SAndy Fiddaman /*
13*d7159b37SAndy Fiddaman * Copyright 2021 OmniOS Community Edition (OmniOSce) Association.
14*d7159b37SAndy Fiddaman */
15*d7159b37SAndy Fiddaman
16*d7159b37SAndy Fiddaman #include <err.h>
17*d7159b37SAndy Fiddaman #include <errno.h>
18*d7159b37SAndy Fiddaman #include <limits.h>
19*d7159b37SAndy Fiddaman #include <stdio.h>
20*d7159b37SAndy Fiddaman #include <stdlib.h>
21*d7159b37SAndy Fiddaman #include <sys/debug.h>
22*d7159b37SAndy Fiddaman #include <sys/eventfd.h>
23*d7159b37SAndy Fiddaman #include <unistd.h>
24*d7159b37SAndy Fiddaman
25*d7159b37SAndy Fiddaman static int
readn(int fd,uint_t n)26*d7159b37SAndy Fiddaman readn(int fd, uint_t n)
27*d7159b37SAndy Fiddaman {
28*d7159b37SAndy Fiddaman uint_t i;
29*d7159b37SAndy Fiddaman int failures = 0;
30*d7159b37SAndy Fiddaman
31*d7159b37SAndy Fiddaman for (i = 0; i < n; i++) {
32*d7159b37SAndy Fiddaman eventfd_t v = 0xdeadbeef;
33*d7159b37SAndy Fiddaman int ret;
34*d7159b37SAndy Fiddaman
35*d7159b37SAndy Fiddaman ret = eventfd_read(fd, &v);
36*d7159b37SAndy Fiddaman if (ret != 0) {
37*d7159b37SAndy Fiddaman warn("Reading %u/%u got ret %d (expected 0)",
38*d7159b37SAndy Fiddaman i + 1, n, ret);
39*d7159b37SAndy Fiddaman failures++;
40*d7159b37SAndy Fiddaman } else if (v != 1) {
41*d7159b37SAndy Fiddaman warnx("Reading %u/%u got value %"PRIu64" (expected 1)",
42*d7159b37SAndy Fiddaman i + 1, n, v);
43*d7159b37SAndy Fiddaman failures++;
44*d7159b37SAndy Fiddaman }
45*d7159b37SAndy Fiddaman }
46*d7159b37SAndy Fiddaman
47*d7159b37SAndy Fiddaman return (failures);
48*d7159b37SAndy Fiddaman }
49*d7159b37SAndy Fiddaman
50*d7159b37SAndy Fiddaman static int
check_nosem(int fd)51*d7159b37SAndy Fiddaman check_nosem(int fd)
52*d7159b37SAndy Fiddaman {
53*d7159b37SAndy Fiddaman eventfd_t v = 0xdeadbeef;
54*d7159b37SAndy Fiddaman int failures = 0;
55*d7159b37SAndy Fiddaman int ret;
56*d7159b37SAndy Fiddaman
57*d7159b37SAndy Fiddaman ret = eventfd_read(fd, &v);
58*d7159b37SAndy Fiddaman
59*d7159b37SAndy Fiddaman if (ret != -1) {
60*d7159b37SAndy Fiddaman warnx("no semaphores read got ret %d (expected -1)", ret);
61*d7159b37SAndy Fiddaman failures++;
62*d7159b37SAndy Fiddaman }
63*d7159b37SAndy Fiddaman
64*d7159b37SAndy Fiddaman if (errno != EAGAIN) {
65*d7159b37SAndy Fiddaman warn("no semaphores read expected EAGAIN but got");
66*d7159b37SAndy Fiddaman failures++;
67*d7159b37SAndy Fiddaman }
68*d7159b37SAndy Fiddaman
69*d7159b37SAndy Fiddaman if (v != 0xdeadbeef) {
70*d7159b37SAndy Fiddaman warnx("no semaphores read modified value to %"PRIx64, v);
71*d7159b37SAndy Fiddaman failures++;
72*d7159b37SAndy Fiddaman }
73*d7159b37SAndy Fiddaman
74*d7159b37SAndy Fiddaman return (failures);
75*d7159b37SAndy Fiddaman }
76*d7159b37SAndy Fiddaman
77*d7159b37SAndy Fiddaman static int
check_badwrite(int fd)78*d7159b37SAndy Fiddaman check_badwrite(int fd)
79*d7159b37SAndy Fiddaman {
80*d7159b37SAndy Fiddaman int failures = 0;
81*d7159b37SAndy Fiddaman int ret;
82*d7159b37SAndy Fiddaman
83*d7159b37SAndy Fiddaman ret = eventfd_write(fd, ULLONG_MAX);
84*d7159b37SAndy Fiddaman
85*d7159b37SAndy Fiddaman if (ret != -1) {
86*d7159b37SAndy Fiddaman warnx("bad write got ret %d (expected -1)", ret);
87*d7159b37SAndy Fiddaman failures++;
88*d7159b37SAndy Fiddaman }
89*d7159b37SAndy Fiddaman
90*d7159b37SAndy Fiddaman if (errno != EINVAL) {
91*d7159b37SAndy Fiddaman warn("bad write expected EINVAL but got");
92*d7159b37SAndy Fiddaman failures++;
93*d7159b37SAndy Fiddaman }
94*d7159b37SAndy Fiddaman
95*d7159b37SAndy Fiddaman return (failures);
96*d7159b37SAndy Fiddaman }
97*d7159b37SAndy Fiddaman
98*d7159b37SAndy Fiddaman int
main(void)99*d7159b37SAndy Fiddaman main(void)
100*d7159b37SAndy Fiddaman {
101*d7159b37SAndy Fiddaman int fd, failures = 0;
102*d7159b37SAndy Fiddaman
103*d7159b37SAndy Fiddaman /* Test eventfd semaphore semantics */
104*d7159b37SAndy Fiddaman fd = eventfd(2, EFD_NONBLOCK | EFD_CLOEXEC | EFD_SEMAPHORE);
105*d7159b37SAndy Fiddaman if (fd == -1)
106*d7159b37SAndy Fiddaman err(EXIT_FAILURE, "Could not create eventfd semaphore");
107*d7159b37SAndy Fiddaman
108*d7159b37SAndy Fiddaman /* Consume the available semaphores */
109*d7159b37SAndy Fiddaman failures += readn(fd, 2);
110*d7159b37SAndy Fiddaman
111*d7159b37SAndy Fiddaman /* The next read should return -1/EAGAIN */
112*d7159b37SAndy Fiddaman failures += check_nosem(fd);
113*d7159b37SAndy Fiddaman
114*d7159b37SAndy Fiddaman /* Return two + three semaphores */
115*d7159b37SAndy Fiddaman if (eventfd_write(fd, 2) != 0) {
116*d7159b37SAndy Fiddaman warn("Error while returning two semaphores");
117*d7159b37SAndy Fiddaman failures++;
118*d7159b37SAndy Fiddaman }
119*d7159b37SAndy Fiddaman if (eventfd_write(fd, 3) != 0) {
120*d7159b37SAndy Fiddaman warn("Error while returning three semaphores");
121*d7159b37SAndy Fiddaman failures++;
122*d7159b37SAndy Fiddaman }
123*d7159b37SAndy Fiddaman
124*d7159b37SAndy Fiddaman /* Consume the available semaphores */
125*d7159b37SAndy Fiddaman failures += readn(fd, 5);
126*d7159b37SAndy Fiddaman
127*d7159b37SAndy Fiddaman /* The next read should return -1/EAGAIN */
128*d7159b37SAndy Fiddaman failures += check_nosem(fd);
129*d7159b37SAndy Fiddaman
130*d7159b37SAndy Fiddaman /*
131*d7159b37SAndy Fiddaman * Check that a writing too large a value results in an error from
132*d7159b37SAndy Fiddaman * eventfd_write() - testing that an error from the underlying write()
133*d7159b37SAndy Fiddaman * is passed back.
134*d7159b37SAndy Fiddaman */
135*d7159b37SAndy Fiddaman failures += check_badwrite(fd);
136*d7159b37SAndy Fiddaman
137*d7159b37SAndy Fiddaman VERIFY0(close(fd));
138*d7159b37SAndy Fiddaman
139*d7159b37SAndy Fiddaman return (failures == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
140*d7159b37SAndy Fiddaman }
141