1 1.3 thorpej /* $NetBSD: t_eventfd.c,v 1.3 2022/02/20 15:21:14 thorpej Exp $ */ 2 1.2 thorpej 3 1.2 thorpej /*- 4 1.2 thorpej * Copyright (c) 2020 The NetBSD Foundation, Inc. 5 1.2 thorpej * All rights reserved. 6 1.2 thorpej * 7 1.2 thorpej * Redistribution and use in source and binary forms, with or without 8 1.2 thorpej * modification, are permitted provided that the following conditions 9 1.2 thorpej * are met: 10 1.2 thorpej * 1. Redistributions of source code must retain the above copyright 11 1.2 thorpej * notice, this list of conditions and the following disclaimer. 12 1.2 thorpej * 2. Redistributions in binary form must reproduce the above copyright 13 1.2 thorpej * notice, this list of conditions and the following disclaimer in the 14 1.2 thorpej * documentation and/or other materials provided with the distribution. 15 1.2 thorpej * 16 1.2 thorpej * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 17 1.2 thorpej * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18 1.2 thorpej * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 1.2 thorpej * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 20 1.2 thorpej * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 1.2 thorpej * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 1.2 thorpej * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 1.2 thorpej * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 1.2 thorpej * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 1.2 thorpej * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 1.2 thorpej * POSSIBILITY OF SUCH DAMAGE. 27 1.2 thorpej */ 28 1.2 thorpej 29 1.2 thorpej #include <sys/cdefs.h> 30 1.2 thorpej __COPYRIGHT("@(#) Copyright (c) 2020\ 31 1.2 thorpej The NetBSD Foundation, inc. All rights reserved."); 32 1.3 thorpej __RCSID("$NetBSD: t_eventfd.c,v 1.3 2022/02/20 15:21:14 thorpej Exp $"); 33 1.2 thorpej 34 1.2 thorpej #include <sys/types.h> 35 1.2 thorpej #include <sys/event.h> 36 1.2 thorpej #include <sys/eventfd.h> 37 1.3 thorpej #include <sys/ioctl.h> 38 1.2 thorpej #include <sys/select.h> 39 1.2 thorpej #include <sys/stat.h> 40 1.2 thorpej #include <sys/syscall.h> 41 1.2 thorpej #include <errno.h> 42 1.2 thorpej #include <poll.h> 43 1.2 thorpej #include <pthread.h> 44 1.2 thorpej #include <stdlib.h> 45 1.2 thorpej #include <stdio.h> 46 1.2 thorpej #include <time.h> 47 1.2 thorpej #include <unistd.h> 48 1.2 thorpej 49 1.2 thorpej #include <atf-c.h> 50 1.2 thorpej 51 1.2 thorpej struct helper_context { 52 1.2 thorpej int efd; 53 1.2 thorpej 54 1.2 thorpej pthread_mutex_t mutex; 55 1.2 thorpej pthread_cond_t cond; 56 1.2 thorpej pthread_barrier_t barrier; 57 1.2 thorpej int state; 58 1.2 thorpej }; 59 1.2 thorpej 60 1.2 thorpej static void 61 1.2 thorpej init_helper_context(struct helper_context * const ctx) 62 1.2 thorpej { 63 1.2 thorpej pthread_condattr_t condattr; 64 1.2 thorpej 65 1.2 thorpej memset(ctx, 0, sizeof(*ctx)); 66 1.2 thorpej 67 1.2 thorpej ATF_REQUIRE(pthread_mutex_init(&ctx->mutex, NULL) == 0); 68 1.2 thorpej 69 1.2 thorpej ATF_REQUIRE(pthread_condattr_init(&condattr) == 0); 70 1.2 thorpej ATF_REQUIRE(pthread_condattr_setclock(&condattr, CLOCK_MONOTONIC) == 0); 71 1.2 thorpej ATF_REQUIRE(pthread_cond_init(&ctx->cond, &condattr) == 0); 72 1.2 thorpej ATF_REQUIRE(pthread_condattr_destroy(&condattr) == 0); 73 1.2 thorpej 74 1.2 thorpej ATF_REQUIRE(pthread_barrier_init(&ctx->barrier, NULL, 2) == 0); 75 1.2 thorpej } 76 1.2 thorpej 77 1.2 thorpej static void 78 1.2 thorpej set_state(struct helper_context * const ctx, int const new) 79 1.2 thorpej { 80 1.2 thorpej pthread_mutex_lock(&ctx->mutex); 81 1.2 thorpej ctx->state = new; 82 1.2 thorpej pthread_cond_signal(&ctx->cond); 83 1.2 thorpej pthread_mutex_unlock(&ctx->mutex); 84 1.2 thorpej } 85 1.2 thorpej 86 1.2 thorpej static int 87 1.2 thorpej get_state(struct helper_context * const ctx) 88 1.2 thorpej { 89 1.2 thorpej int rv; 90 1.2 thorpej 91 1.2 thorpej pthread_mutex_lock(&ctx->mutex); 92 1.2 thorpej rv = ctx->state; 93 1.2 thorpej pthread_mutex_unlock(&ctx->mutex); 94 1.2 thorpej 95 1.2 thorpej return rv; 96 1.2 thorpej } 97 1.2 thorpej 98 1.2 thorpej static bool 99 1.2 thorpej wait_state(struct helper_context * const ctx, int const val) 100 1.2 thorpej { 101 1.2 thorpej struct timespec deadline; 102 1.2 thorpej int error; 103 1.2 thorpej bool rv; 104 1.2 thorpej 105 1.2 thorpej pthread_mutex_lock(&ctx->mutex); 106 1.2 thorpej 107 1.2 thorpej ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &deadline) == 0); 108 1.2 thorpej deadline.tv_sec += 5; 109 1.2 thorpej 110 1.2 thorpej while (ctx->state != val) { 111 1.2 thorpej error = pthread_cond_timedwait(&ctx->cond, &ctx->mutex, 112 1.2 thorpej &deadline); 113 1.2 thorpej if (error) { 114 1.2 thorpej break; 115 1.2 thorpej } 116 1.2 thorpej } 117 1.2 thorpej rv = ctx->state == val; 118 1.2 thorpej 119 1.2 thorpej pthread_mutex_unlock(&ctx->mutex); 120 1.2 thorpej 121 1.2 thorpej return rv; 122 1.2 thorpej } 123 1.2 thorpej 124 1.2 thorpej static bool 125 1.2 thorpej wait_barrier(struct helper_context * const ctx) 126 1.2 thorpej { 127 1.2 thorpej int rv = pthread_barrier_wait(&ctx->barrier); 128 1.2 thorpej 129 1.2 thorpej return rv == 0 || rv == PTHREAD_BARRIER_SERIAL_THREAD; 130 1.2 thorpej } 131 1.2 thorpej 132 1.2 thorpej /*****************************************************************************/ 133 1.2 thorpej 134 1.2 thorpej static void * 135 1.2 thorpej eventfd_normal_helper(void * const v) 136 1.2 thorpej { 137 1.2 thorpej struct helper_context * const ctx = v; 138 1.2 thorpej eventfd_t efd_value; 139 1.2 thorpej 140 1.2 thorpej ATF_REQUIRE(wait_barrier(ctx)); 141 1.2 thorpej 142 1.2 thorpej /* Read the value. This will reset it to zero. */ 143 1.2 thorpej ATF_REQUIRE(get_state(ctx) == 666); 144 1.2 thorpej ATF_REQUIRE(eventfd_read(ctx->efd, &efd_value) == 0); 145 1.2 thorpej 146 1.2 thorpej /* Assert the value. */ 147 1.2 thorpej ATF_REQUIRE(efd_value == 0xcafebabe); 148 1.2 thorpej 149 1.2 thorpej set_state(ctx, 0); 150 1.2 thorpej 151 1.2 thorpej /* Wait for the main thread to prep the next test. */ 152 1.2 thorpej ATF_REQUIRE(wait_barrier(ctx)); 153 1.2 thorpej 154 1.2 thorpej /* Read the value. */ 155 1.2 thorpej ATF_REQUIRE(eventfd_read(ctx->efd, &efd_value) == 0); 156 1.2 thorpej 157 1.2 thorpej /* Assert the value. */ 158 1.2 thorpej ATF_REQUIRE(efd_value == 0xbeefcafe); 159 1.2 thorpej 160 1.2 thorpej ATF_REQUIRE(wait_barrier(ctx)); 161 1.2 thorpej 162 1.2 thorpej return NULL; 163 1.2 thorpej } 164 1.2 thorpej 165 1.2 thorpej ATF_TC(eventfd_normal); 166 1.2 thorpej ATF_TC_HEAD(eventfd_normal, tc) 167 1.2 thorpej { 168 1.2 thorpej atf_tc_set_md_var(tc, "descr", 169 1.2 thorpej "validates basic normal eventfd operation"); 170 1.2 thorpej } 171 1.2 thorpej ATF_TC_BODY(eventfd_normal, tc) 172 1.2 thorpej { 173 1.2 thorpej struct helper_context ctx; 174 1.2 thorpej pthread_t helper; 175 1.2 thorpej void *join_val; 176 1.2 thorpej 177 1.2 thorpej init_helper_context(&ctx); 178 1.2 thorpej 179 1.2 thorpej ATF_REQUIRE((ctx.efd = eventfd(0, 0)) >= 0); 180 1.2 thorpej 181 1.2 thorpej ATF_REQUIRE(pthread_create(&helper, NULL, 182 1.2 thorpej eventfd_normal_helper, &ctx) == 0); 183 1.2 thorpej 184 1.2 thorpej /* 185 1.2 thorpej * Wait for the helper to block in read(). Give it some time 186 1.2 thorpej * so that if the read fails or returns immediately, we'll 187 1.2 thorpej * notice. 188 1.2 thorpej */ 189 1.2 thorpej set_state(&ctx, 666); 190 1.2 thorpej ATF_REQUIRE(wait_barrier(&ctx)); 191 1.2 thorpej sleep(2); 192 1.2 thorpej ATF_REQUIRE(get_state(&ctx) == 666); 193 1.2 thorpej 194 1.2 thorpej /* Write a distinct value; helper will assert it. */ 195 1.2 thorpej ATF_REQUIRE(eventfd_write(ctx.efd, 0xcafebabe) == 0); 196 1.2 thorpej 197 1.2 thorpej /* Wait for helper to read the value. */ 198 1.2 thorpej ATF_REQUIRE(wait_state(&ctx, 0)); 199 1.2 thorpej 200 1.2 thorpej /* Helper is now blocked in a barrier. */ 201 1.2 thorpej 202 1.2 thorpej /* Test additive property of the efd value. */ 203 1.2 thorpej ATF_REQUIRE(eventfd_write(ctx.efd, 0x0000cafe) == 0); 204 1.2 thorpej ATF_REQUIRE(eventfd_write(ctx.efd, 0xbeef0000) == 0); 205 1.2 thorpej 206 1.2 thorpej /* Satisfy the barrier; helper will read value and assert 0xbeefcafe. */ 207 1.2 thorpej ATF_REQUIRE(wait_barrier(&ctx)); 208 1.2 thorpej 209 1.2 thorpej /* And wait for it to finish. */ 210 1.2 thorpej ATF_REQUIRE(wait_barrier(&ctx)); 211 1.2 thorpej 212 1.2 thorpej /* Reap the helper. */ 213 1.2 thorpej ATF_REQUIRE(pthread_join(helper, &join_val) == 0); 214 1.2 thorpej 215 1.2 thorpej (void) close(ctx.efd); 216 1.2 thorpej } 217 1.2 thorpej 218 1.2 thorpej /*****************************************************************************/ 219 1.2 thorpej 220 1.2 thorpej ATF_TC(eventfd_semaphore); 221 1.2 thorpej ATF_TC_HEAD(eventfd_semaphore, tc) 222 1.2 thorpej { 223 1.2 thorpej atf_tc_set_md_var(tc, "descr", 224 1.2 thorpej "validates semaphore and non-blocking eventfd operation"); 225 1.2 thorpej } 226 1.2 thorpej ATF_TC_BODY(eventfd_semaphore, tc) 227 1.2 thorpej { 228 1.2 thorpej eventfd_t efd_value; 229 1.2 thorpej int efd; 230 1.2 thorpej 231 1.2 thorpej ATF_REQUIRE((efd = eventfd(3, EFD_SEMAPHORE | EFD_NONBLOCK)) >= 0); 232 1.2 thorpej 233 1.2 thorpej /* 3 reads should succeed without blocking. */ 234 1.2 thorpej ATF_REQUIRE(eventfd_read(efd, &efd_value) == 0); 235 1.2 thorpej ATF_REQUIRE(efd_value == 1); 236 1.2 thorpej 237 1.2 thorpej ATF_REQUIRE(eventfd_read(efd, &efd_value) == 0); 238 1.2 thorpej ATF_REQUIRE(efd_value == 1); 239 1.2 thorpej 240 1.2 thorpej ATF_REQUIRE(eventfd_read(efd, &efd_value) == 0); 241 1.2 thorpej ATF_REQUIRE(efd_value == 1); 242 1.2 thorpej 243 1.2 thorpej /* This one should block. */ 244 1.2 thorpej ATF_REQUIRE_ERRNO(EAGAIN, 245 1.2 thorpej eventfd_read(efd, &efd_value) == -1); 246 1.2 thorpej 247 1.2 thorpej /* Add 1 to the semaphore. */ 248 1.2 thorpej ATF_REQUIRE(eventfd_write(efd, 1) == 0); 249 1.2 thorpej 250 1.2 thorpej /* One more read allowed. */ 251 1.2 thorpej ATF_REQUIRE(eventfd_read(efd, &efd_value) == 0); 252 1.2 thorpej ATF_REQUIRE(efd_value == 1); 253 1.2 thorpej 254 1.2 thorpej /* And this one again should block. */ 255 1.2 thorpej ATF_REQUIRE_ERRNO(EAGAIN, 256 1.2 thorpej eventfd_read(efd, &efd_value) == -1); 257 1.2 thorpej 258 1.2 thorpej (void) close(efd); 259 1.2 thorpej } 260 1.2 thorpej 261 1.2 thorpej /*****************************************************************************/ 262 1.2 thorpej 263 1.2 thorpej ATF_TC(eventfd_select_poll_kevent_immed); 264 1.2 thorpej ATF_TC_HEAD(eventfd_select_poll_kevent_immed, tc) 265 1.2 thorpej { 266 1.2 thorpej atf_tc_set_md_var(tc, "descr", 267 1.2 thorpej "validates select/poll/kevent behavior - immediate return"); 268 1.2 thorpej } 269 1.2 thorpej ATF_TC_BODY(eventfd_select_poll_kevent_immed, tc) 270 1.2 thorpej { 271 1.2 thorpej const struct timespec ts = { .tv_sec = 0, .tv_nsec = 0 }; 272 1.2 thorpej struct timeval tv; 273 1.2 thorpej struct pollfd fds[1]; 274 1.2 thorpej fd_set readfds, writefds, exceptfds; 275 1.2 thorpej int efd; 276 1.2 thorpej int kq; 277 1.2 thorpej struct kevent kev[2]; 278 1.2 thorpej 279 1.2 thorpej ATF_REQUIRE((efd = eventfd(0, EFD_NONBLOCK)) >= 0); 280 1.2 thorpej 281 1.2 thorpej ATF_REQUIRE((kq = kqueue()) >= 0); 282 1.2 thorpej EV_SET(&kev[0], efd, EVFILT_READ, EV_ADD, 0, 0, NULL); 283 1.2 thorpej EV_SET(&kev[1], efd, EVFILT_WRITE, EV_ADD, 0, 0, NULL); 284 1.2 thorpej ATF_REQUIRE(kevent(kq, kev, 2, NULL, 0, &ts) == 0); 285 1.2 thorpej 286 1.2 thorpej /* 287 1.2 thorpej * efd should be writable but not readable. Pass all of the 288 1.2 thorpej * event bits; we should only get back POLLOUT | POLLWRNORM. 289 1.2 thorpej */ 290 1.2 thorpej fds[0].fd = efd; 291 1.2 thorpej fds[0].events = POLLIN | POLLRDNORM | POLLRDBAND | POLLPRI | 292 1.2 thorpej POLLOUT | POLLWRNORM | POLLWRBAND | POLLHUP; 293 1.2 thorpej fds[0].revents = 0; 294 1.2 thorpej ATF_REQUIRE(poll(fds, 1, 0) == 1); 295 1.2 thorpej ATF_REQUIRE(fds[0].revents == (POLLOUT | POLLWRNORM)); 296 1.2 thorpej 297 1.2 thorpej /* 298 1.2 thorpej * As above; efd should only be set in writefds upon return 299 1.2 thorpej * from the select() call. 300 1.2 thorpej */ 301 1.2 thorpej FD_ZERO(&readfds); 302 1.2 thorpej FD_ZERO(&writefds); 303 1.2 thorpej FD_ZERO(&exceptfds); 304 1.2 thorpej tv.tv_sec = 0; 305 1.2 thorpej tv.tv_usec = 0; 306 1.2 thorpej FD_SET(efd, &readfds); 307 1.2 thorpej FD_SET(efd, &writefds); 308 1.2 thorpej FD_SET(efd, &exceptfds); 309 1.2 thorpej ATF_REQUIRE(select(efd + 1, &readfds, &writefds, &exceptfds, &tv) == 1); 310 1.2 thorpej ATF_REQUIRE(!FD_ISSET(efd, &readfds)); 311 1.2 thorpej ATF_REQUIRE(FD_ISSET(efd, &writefds)); 312 1.2 thorpej ATF_REQUIRE(!FD_ISSET(efd, &exceptfds)); 313 1.2 thorpej 314 1.2 thorpej /* 315 1.2 thorpej * Check that we get an EVFILT_WRITE event (and only that event) 316 1.2 thorpej * on efd. 317 1.2 thorpej */ 318 1.2 thorpej memset(kev, 0, sizeof(kev)); 319 1.2 thorpej ATF_REQUIRE(kevent(kq, NULL, 0, kev, 2, &ts) == 1); 320 1.2 thorpej ATF_REQUIRE(kev[0].ident == (uintptr_t)efd); 321 1.2 thorpej ATF_REQUIRE(kev[0].filter == EVFILT_WRITE); 322 1.2 thorpej ATF_REQUIRE((kev[0].flags & (EV_EOF | EV_ERROR)) == 0); 323 1.2 thorpej ATF_REQUIRE(kev[0].data == 0); 324 1.2 thorpej 325 1.2 thorpej /* 326 1.2 thorpej * Write the maximum value into the eventfd. This should result 327 1.2 thorpej * in the eventfd becoming readable but NOT writable. 328 1.2 thorpej */ 329 1.2 thorpej ATF_REQUIRE(eventfd_write(efd, UINT64_MAX - 1) == 0); 330 1.2 thorpej 331 1.2 thorpej fds[0].fd = efd; 332 1.2 thorpej fds[0].events = POLLIN | POLLRDNORM | POLLRDBAND | POLLPRI | 333 1.2 thorpej POLLOUT | POLLWRNORM | POLLWRBAND | POLLHUP; 334 1.2 thorpej fds[0].revents = 0; 335 1.2 thorpej ATF_REQUIRE(poll(fds, 1, 0) == 1); 336 1.2 thorpej ATF_REQUIRE(fds[0].revents == (POLLIN | POLLRDNORM)); 337 1.2 thorpej 338 1.2 thorpej FD_ZERO(&readfds); 339 1.2 thorpej FD_ZERO(&writefds); 340 1.2 thorpej FD_ZERO(&exceptfds); 341 1.2 thorpej tv.tv_sec = 0; 342 1.2 thorpej tv.tv_usec = 0; 343 1.2 thorpej FD_SET(efd, &readfds); 344 1.2 thorpej FD_SET(efd, &writefds); 345 1.2 thorpej FD_SET(efd, &exceptfds); 346 1.2 thorpej ATF_REQUIRE(select(efd + 1, &readfds, &writefds, &exceptfds, &tv) == 1); 347 1.2 thorpej ATF_REQUIRE(FD_ISSET(efd, &readfds)); 348 1.2 thorpej ATF_REQUIRE(!FD_ISSET(efd, &writefds)); 349 1.2 thorpej ATF_REQUIRE(!FD_ISSET(efd, &exceptfds)); 350 1.2 thorpej 351 1.2 thorpej /* 352 1.2 thorpej * Check that we get an EVFILT_READ event (and only that event) 353 1.2 thorpej * on efd. 354 1.2 thorpej */ 355 1.2 thorpej memset(kev, 0, sizeof(kev)); 356 1.2 thorpej ATF_REQUIRE(kevent(kq, NULL, 0, kev, 2, &ts) == 1); 357 1.2 thorpej ATF_REQUIRE(kev[0].ident == (uintptr_t)efd); 358 1.2 thorpej ATF_REQUIRE(kev[0].filter == EVFILT_READ); 359 1.2 thorpej ATF_REQUIRE((kev[0].flags & (EV_EOF | EV_ERROR)) == 0); 360 1.2 thorpej ATF_REQUIRE(kev[0].data == (int64_t)(UINT64_MAX - 1)); 361 1.2 thorpej 362 1.2 thorpej (void) close(kq); 363 1.2 thorpej (void) close(efd); 364 1.2 thorpej } 365 1.2 thorpej 366 1.2 thorpej /*****************************************************************************/ 367 1.2 thorpej 368 1.2 thorpej static void * 369 1.2 thorpej eventfd_select_poll_kevent_block_helper(void * const v) 370 1.2 thorpej { 371 1.2 thorpej struct helper_context * const ctx = v; 372 1.2 thorpej struct pollfd fds[1]; 373 1.2 thorpej fd_set selfds; 374 1.2 thorpej eventfd_t efd_value; 375 1.2 thorpej int kq; 376 1.2 thorpej struct kevent kev[1]; 377 1.2 thorpej 378 1.2 thorpej fds[0].fd = ctx->efd; 379 1.2 thorpej fds[0].events = POLLIN | POLLRDNORM | POLLRDBAND | POLLPRI; 380 1.2 thorpej fds[0].revents = 0; 381 1.2 thorpej 382 1.2 thorpej ATF_REQUIRE_ERRNO(EAGAIN, 383 1.2 thorpej eventfd_read(ctx->efd, &efd_value) == -1); 384 1.2 thorpej 385 1.2 thorpej ATF_REQUIRE(wait_barrier(ctx)); 386 1.2 thorpej 387 1.2 thorpej ATF_REQUIRE(get_state(ctx) == 666); 388 1.2 thorpej ATF_REQUIRE(poll(fds, 1, INFTIM) == 1); 389 1.2 thorpej ATF_REQUIRE(fds[0].revents == (POLLIN | POLLRDNORM)); 390 1.2 thorpej set_state(ctx, 0); 391 1.2 thorpej 392 1.2 thorpej ATF_REQUIRE(wait_barrier(ctx)); 393 1.2 thorpej 394 1.2 thorpej /* 395 1.2 thorpej * The maximum value was written to the eventfd, so we 396 1.2 thorpej * should block waiting for writability. 397 1.2 thorpej */ 398 1.2 thorpej fds[0].fd = ctx->efd; 399 1.2 thorpej fds[0].events = POLLOUT | POLLWRNORM; 400 1.2 thorpej fds[0].revents = 0; 401 1.2 thorpej 402 1.2 thorpej ATF_REQUIRE_ERRNO(EAGAIN, 403 1.2 thorpej eventfd_write(ctx->efd, UINT64_MAX - 1) == -1); 404 1.2 thorpej 405 1.2 thorpej ATF_REQUIRE(wait_barrier(ctx)); 406 1.2 thorpej 407 1.2 thorpej ATF_REQUIRE(get_state(ctx) == 666); 408 1.2 thorpej ATF_REQUIRE(poll(fds, 1, INFTIM) == 1); 409 1.2 thorpej ATF_REQUIRE(fds[0].revents == (POLLOUT | POLLWRNORM)); 410 1.2 thorpej set_state(ctx, 0); 411 1.2 thorpej 412 1.2 thorpej ATF_REQUIRE(wait_barrier(ctx)); 413 1.2 thorpej 414 1.2 thorpej /* 415 1.2 thorpej * Now, the same dance again, with select(). 416 1.2 thorpej */ 417 1.2 thorpej 418 1.2 thorpej FD_ZERO(&selfds); 419 1.2 thorpej FD_SET(ctx->efd, &selfds); 420 1.2 thorpej 421 1.2 thorpej ATF_REQUIRE_ERRNO(EAGAIN, 422 1.2 thorpej eventfd_read(ctx->efd, &efd_value) == -1); 423 1.2 thorpej 424 1.2 thorpej ATF_REQUIRE(wait_barrier(ctx)); 425 1.2 thorpej 426 1.2 thorpej ATF_REQUIRE(get_state(ctx) == 666); 427 1.2 thorpej ATF_REQUIRE(select(ctx->efd + 1, &selfds, NULL, NULL, NULL) == 1); 428 1.2 thorpej ATF_REQUIRE(FD_ISSET(ctx->efd, &selfds)); 429 1.2 thorpej set_state(ctx, 0); 430 1.2 thorpej 431 1.2 thorpej ATF_REQUIRE(wait_barrier(ctx)); 432 1.2 thorpej 433 1.2 thorpej FD_ZERO(&selfds); 434 1.2 thorpej FD_SET(ctx->efd, &selfds); 435 1.2 thorpej 436 1.2 thorpej ATF_REQUIRE_ERRNO(EAGAIN, 437 1.2 thorpej eventfd_write(ctx->efd, UINT64_MAX - 1) == -1); 438 1.2 thorpej 439 1.2 thorpej ATF_REQUIRE(wait_barrier(ctx)); 440 1.2 thorpej 441 1.2 thorpej ATF_REQUIRE(get_state(ctx) == 666); 442 1.2 thorpej ATF_REQUIRE(select(ctx->efd + 1, NULL, &selfds, NULL, NULL) == 1); 443 1.2 thorpej ATF_REQUIRE(FD_ISSET(ctx->efd, &selfds)); 444 1.2 thorpej set_state(ctx, 0); 445 1.2 thorpej 446 1.2 thorpej ATF_REQUIRE(wait_barrier(ctx)); 447 1.2 thorpej 448 1.2 thorpej /* 449 1.2 thorpej * Now, the same dance again, with kevent(). 450 1.2 thorpej */ 451 1.2 thorpej ATF_REQUIRE((kq = kqueue()) >= 0); 452 1.2 thorpej 453 1.2 thorpej EV_SET(&kev[0], ctx->efd, EVFILT_READ, EV_ADD | EV_ONESHOT, 0, 0, NULL); 454 1.2 thorpej ATF_REQUIRE(kevent(kq, kev, 1, NULL, 0, NULL) == 0); 455 1.2 thorpej 456 1.2 thorpej ATF_REQUIRE_ERRNO(EAGAIN, 457 1.2 thorpej eventfd_read(ctx->efd, &efd_value) == -1); 458 1.2 thorpej 459 1.2 thorpej ATF_REQUIRE(wait_barrier(ctx)); 460 1.2 thorpej 461 1.2 thorpej ATF_REQUIRE(get_state(ctx) == 666); 462 1.2 thorpej ATF_REQUIRE(kevent(kq, NULL, 0, kev, 1, NULL) == 1); 463 1.2 thorpej ATF_REQUIRE(kev[0].ident == (uintptr_t)ctx->efd); 464 1.2 thorpej ATF_REQUIRE(kev[0].filter == EVFILT_READ); 465 1.2 thorpej ATF_REQUIRE((kev[0].flags & (EV_EOF | EV_ERROR)) == 0); 466 1.2 thorpej ATF_REQUIRE(kev[0].data == (int64_t)(UINT64_MAX - 1)); 467 1.2 thorpej set_state(ctx, 0); 468 1.2 thorpej 469 1.2 thorpej ATF_REQUIRE(wait_barrier(ctx)); 470 1.2 thorpej 471 1.2 thorpej EV_SET(&kev[0], ctx->efd, EVFILT_WRITE, EV_ADD | EV_ONESHOT, 0, 0, 472 1.2 thorpej NULL); 473 1.2 thorpej ATF_REQUIRE(kevent(kq, kev, 1, NULL, 0, NULL) == 0); 474 1.2 thorpej 475 1.2 thorpej ATF_REQUIRE_ERRNO(EAGAIN, 476 1.2 thorpej eventfd_write(ctx->efd, UINT64_MAX - 1) == -1); 477 1.2 thorpej 478 1.2 thorpej ATF_REQUIRE(wait_barrier(ctx)); 479 1.2 thorpej 480 1.2 thorpej ATF_REQUIRE(get_state(ctx) == 666); 481 1.2 thorpej ATF_REQUIRE(kevent(kq, NULL, 0, kev, 1, NULL) == 1); 482 1.2 thorpej ATF_REQUIRE(kev[0].ident == (uintptr_t)ctx->efd); 483 1.2 thorpej ATF_REQUIRE(kev[0].filter == EVFILT_WRITE); 484 1.2 thorpej ATF_REQUIRE((kev[0].flags & (EV_EOF | EV_ERROR)) == 0); 485 1.2 thorpej ATF_REQUIRE(kev[0].data == 0); 486 1.2 thorpej set_state(ctx, 0); 487 1.2 thorpej 488 1.2 thorpej ATF_REQUIRE(wait_barrier(ctx)); 489 1.2 thorpej 490 1.2 thorpej (void) close(kq); 491 1.2 thorpej 492 1.2 thorpej return NULL; 493 1.2 thorpej } 494 1.2 thorpej 495 1.2 thorpej ATF_TC(eventfd_select_poll_kevent_block); 496 1.2 thorpej ATF_TC_HEAD(eventfd_select_poll_kevent_block, tc) 497 1.2 thorpej { 498 1.2 thorpej atf_tc_set_md_var(tc, "descr", 499 1.2 thorpej "validates select/poll/kevent behavior - return after blocking"); 500 1.2 thorpej } 501 1.2 thorpej ATF_TC_BODY(eventfd_select_poll_kevent_block, tc) 502 1.2 thorpej { 503 1.2 thorpej struct helper_context ctx; 504 1.2 thorpej pthread_t helper; 505 1.2 thorpej eventfd_t efd_value; 506 1.2 thorpej void *join_val; 507 1.2 thorpej 508 1.2 thorpej init_helper_context(&ctx); 509 1.2 thorpej 510 1.2 thorpej ATF_REQUIRE((ctx.efd = eventfd(0, EFD_NONBLOCK)) >= 0); 511 1.2 thorpej 512 1.2 thorpej ATF_REQUIRE(pthread_create(&helper, NULL, 513 1.2 thorpej eventfd_select_poll_kevent_block_helper, 514 1.2 thorpej &ctx) == 0); 515 1.2 thorpej 516 1.2 thorpej /* 517 1.2 thorpej * Wait for the helper to block in poll(). Give it some time 518 1.2 thorpej * so that if the poll returns immediately, we'll notice. 519 1.2 thorpej */ 520 1.2 thorpej set_state(&ctx, 666); 521 1.2 thorpej ATF_REQUIRE(wait_barrier(&ctx)); 522 1.2 thorpej sleep(2); 523 1.2 thorpej ATF_REQUIRE(get_state(&ctx) == 666); 524 1.2 thorpej 525 1.2 thorpej /* 526 1.2 thorpej * Write the max value to the eventfd so that it becomes readable 527 1.2 thorpej * and unblocks the helper waiting in poll(). 528 1.2 thorpej */ 529 1.2 thorpej ATF_REQUIRE(eventfd_write(ctx.efd, UINT64_MAX - 1) == 0); 530 1.2 thorpej 531 1.2 thorpej /* 532 1.2 thorpej * Ensure the helper woke from the poll() call. 533 1.2 thorpej */ 534 1.2 thorpej ATF_REQUIRE(wait_barrier(&ctx)); 535 1.2 thorpej ATF_REQUIRE(get_state(&ctx) == 0); 536 1.2 thorpej 537 1.2 thorpej /* 538 1.2 thorpej * Wait for the helper to block in poll(), this time waiting 539 1.2 thorpej * for writability. 540 1.2 thorpej */ 541 1.2 thorpej set_state(&ctx, 666); 542 1.2 thorpej ATF_REQUIRE(wait_barrier(&ctx)); 543 1.2 thorpej sleep(2); 544 1.2 thorpej ATF_REQUIRE(get_state(&ctx) == 666); 545 1.2 thorpej 546 1.2 thorpej /* 547 1.2 thorpej * Now read the value, which will reset the eventfd to 0 and 548 1.2 thorpej * unblock the poll() call. 549 1.2 thorpej */ 550 1.2 thorpej ATF_REQUIRE(eventfd_read(ctx.efd, &efd_value) == 0); 551 1.2 thorpej ATF_REQUIRE(efd_value == UINT64_MAX - 1); 552 1.2 thorpej 553 1.2 thorpej /* 554 1.2 thorpej * Ensure that the helper woke from the poll() call. 555 1.2 thorpej */ 556 1.2 thorpej ATF_REQUIRE(wait_barrier(&ctx)); 557 1.2 thorpej ATF_REQUIRE(get_state(&ctx) == 0); 558 1.2 thorpej 559 1.2 thorpej /* 560 1.2 thorpej * Wait for the helper to block in select(), waiting for readability. 561 1.2 thorpej */ 562 1.2 thorpej set_state(&ctx, 666); 563 1.2 thorpej ATF_REQUIRE(wait_barrier(&ctx)); 564 1.2 thorpej sleep(2); 565 1.2 thorpej ATF_REQUIRE(get_state(&ctx) == 666); 566 1.2 thorpej 567 1.2 thorpej /* 568 1.2 thorpej * Write the max value to the eventfd so that it becomes readable 569 1.2 thorpej * and unblocks the helper waiting in select(). 570 1.2 thorpej */ 571 1.2 thorpej efd_value = UINT64_MAX - 1; 572 1.2 thorpej ATF_REQUIRE(eventfd_write(ctx.efd, UINT64_MAX - 1) == 0); 573 1.2 thorpej 574 1.2 thorpej /* 575 1.2 thorpej * Ensure the helper woke from the select() call. 576 1.2 thorpej */ 577 1.2 thorpej ATF_REQUIRE(wait_barrier(&ctx)); 578 1.2 thorpej ATF_REQUIRE(get_state(&ctx) == 0); 579 1.2 thorpej 580 1.2 thorpej /* 581 1.2 thorpej * Wait for the helper to block in select(), this time waiting 582 1.2 thorpej * for writability. 583 1.2 thorpej */ 584 1.2 thorpej set_state(&ctx, 666); 585 1.2 thorpej ATF_REQUIRE(wait_barrier(&ctx)); 586 1.2 thorpej sleep(2); 587 1.2 thorpej ATF_REQUIRE(get_state(&ctx) == 666); 588 1.2 thorpej 589 1.2 thorpej /* 590 1.2 thorpej * Now read the value, which will reset the eventfd to 0 and 591 1.2 thorpej * unblock the select() call. 592 1.2 thorpej */ 593 1.2 thorpej ATF_REQUIRE(eventfd_read(ctx.efd, &efd_value) == 0); 594 1.2 thorpej ATF_REQUIRE(efd_value == UINT64_MAX - 1); 595 1.2 thorpej 596 1.2 thorpej /* 597 1.2 thorpej * Ensure that the helper woke from the select() call. 598 1.2 thorpej */ 599 1.2 thorpej ATF_REQUIRE(wait_barrier(&ctx)); 600 1.2 thorpej ATF_REQUIRE(get_state(&ctx) == 0); 601 1.2 thorpej 602 1.2 thorpej /* 603 1.2 thorpej * Wait for the helper to block in kevent(), waiting for readability. 604 1.2 thorpej */ 605 1.2 thorpej set_state(&ctx, 666); 606 1.2 thorpej ATF_REQUIRE(wait_barrier(&ctx)); 607 1.2 thorpej sleep(2); 608 1.2 thorpej ATF_REQUIRE(get_state(&ctx) == 666); 609 1.2 thorpej 610 1.2 thorpej /* 611 1.2 thorpej * Write the max value to the eventfd so that it becomes readable 612 1.2 thorpej * and unblocks the helper waiting in kevent(). 613 1.2 thorpej */ 614 1.2 thorpej efd_value = UINT64_MAX - 1; 615 1.2 thorpej ATF_REQUIRE(eventfd_write(ctx.efd, UINT64_MAX - 1) == 0); 616 1.2 thorpej 617 1.2 thorpej /* 618 1.2 thorpej * Ensure the helper woke from the kevent() call. 619 1.2 thorpej */ 620 1.2 thorpej ATF_REQUIRE(wait_barrier(&ctx)); 621 1.2 thorpej ATF_REQUIRE(get_state(&ctx) == 0); 622 1.2 thorpej 623 1.2 thorpej /* 624 1.2 thorpej * Wait for the helper to block in kevent(), this time waiting 625 1.2 thorpej * for writability. 626 1.2 thorpej */ 627 1.2 thorpej set_state(&ctx, 666); 628 1.2 thorpej ATF_REQUIRE(wait_barrier(&ctx)); 629 1.2 thorpej sleep(2); 630 1.2 thorpej ATF_REQUIRE(get_state(&ctx) == 666); 631 1.2 thorpej 632 1.2 thorpej /* 633 1.2 thorpej * Now read the value, which will reset the eventfd to 0 and 634 1.2 thorpej * unblock the select() call. 635 1.2 thorpej */ 636 1.2 thorpej ATF_REQUIRE(eventfd_read(ctx.efd, &efd_value) == 0); 637 1.2 thorpej ATF_REQUIRE(efd_value == UINT64_MAX - 1); 638 1.2 thorpej 639 1.2 thorpej /* 640 1.2 thorpej * Ensure that the helper woke from the kevent() call. 641 1.2 thorpej */ 642 1.2 thorpej ATF_REQUIRE(wait_barrier(&ctx)); 643 1.2 thorpej ATF_REQUIRE(get_state(&ctx) == 0); 644 1.2 thorpej 645 1.2 thorpej /* Reap the helper. */ 646 1.2 thorpej ATF_REQUIRE(pthread_join(helper, &join_val) == 0); 647 1.2 thorpej 648 1.2 thorpej (void) close(ctx.efd); 649 1.2 thorpej } 650 1.2 thorpej 651 1.2 thorpej /*****************************************************************************/ 652 1.2 thorpej 653 1.2 thorpej static void * 654 1.2 thorpej eventfd_restart_helper(void * const v) 655 1.2 thorpej { 656 1.2 thorpej struct helper_context * const ctx = v; 657 1.2 thorpej eventfd_t efd_value; 658 1.2 thorpej 659 1.2 thorpej /* 660 1.2 thorpej * Issue a single read to ensure that the descriptor is valid. 661 1.2 thorpej * Thius will not block because it was created with an initial 662 1.2 thorpej * count of 1. 663 1.2 thorpej */ 664 1.2 thorpej ATF_REQUIRE(eventfd_read(ctx->efd, &efd_value) == 0); 665 1.2 thorpej ATF_REQUIRE(efd_value == 1); 666 1.2 thorpej 667 1.2 thorpej ATF_REQUIRE(wait_barrier(ctx)); 668 1.2 thorpej 669 1.2 thorpej /* 670 1.2 thorpej * Block in read. The main thread will close the descriptor, 671 1.2 thorpej * which should unblock us and result in EBADF. 672 1.2 thorpej */ 673 1.2 thorpej ATF_REQUIRE(get_state(ctx) == 666); 674 1.2 thorpej ATF_REQUIRE_ERRNO(EBADF, eventfd_read(ctx->efd, &efd_value) == -1); 675 1.2 thorpej set_state(ctx, 0); 676 1.2 thorpej 677 1.2 thorpej ATF_REQUIRE(wait_barrier(ctx)); 678 1.2 thorpej 679 1.2 thorpej return NULL; 680 1.2 thorpej } 681 1.2 thorpej 682 1.2 thorpej ATF_TC(eventfd_restart); 683 1.2 thorpej ATF_TC_HEAD(eventfd_restart, tc) 684 1.2 thorpej { 685 1.2 thorpej atf_tc_set_md_var(tc, "descr", 686 1.2 thorpej "exercises the 'restart' fileop code path"); 687 1.2 thorpej } 688 1.2 thorpej ATF_TC_BODY(eventfd_restart, tc) 689 1.2 thorpej { 690 1.2 thorpej struct helper_context ctx; 691 1.2 thorpej pthread_t helper; 692 1.2 thorpej void *join_val; 693 1.2 thorpej 694 1.2 thorpej init_helper_context(&ctx); 695 1.2 thorpej 696 1.2 thorpej ATF_REQUIRE((ctx.efd = eventfd(1, 0)) >= 0); 697 1.2 thorpej 698 1.2 thorpej ATF_REQUIRE(pthread_create(&helper, NULL, 699 1.2 thorpej eventfd_restart_helper, &ctx) == 0); 700 1.2 thorpej 701 1.2 thorpej /* 702 1.2 thorpej * Wait for the helper to block in read(). Give it some time 703 1.2 thorpej * so that if the poll returns immediately, we'll notice. 704 1.2 thorpej */ 705 1.2 thorpej set_state(&ctx, 666); 706 1.2 thorpej ATF_REQUIRE(wait_barrier(&ctx)); 707 1.2 thorpej sleep(2); 708 1.2 thorpej ATF_REQUIRE(get_state(&ctx) == 666); 709 1.2 thorpej 710 1.2 thorpej /* 711 1.2 thorpej * Close the descriptor. This should unblock the reader, 712 1.2 thorpej * and cause it to receive EBADF. 713 1.2 thorpej */ 714 1.2 thorpej ATF_REQUIRE(close(ctx.efd) == 0); 715 1.2 thorpej 716 1.2 thorpej /* 717 1.2 thorpej * Ensure that the helper woke from the read() call. 718 1.2 thorpej */ 719 1.2 thorpej ATF_REQUIRE(wait_barrier(&ctx)); 720 1.2 thorpej ATF_REQUIRE(get_state(&ctx) == 0); 721 1.2 thorpej 722 1.2 thorpej /* Reap the helper. */ 723 1.2 thorpej ATF_REQUIRE(pthread_join(helper, &join_val) == 0); 724 1.2 thorpej } 725 1.2 thorpej 726 1.2 thorpej /*****************************************************************************/ 727 1.2 thorpej 728 1.2 thorpej ATF_TC(eventfd_badflags); 729 1.2 thorpej ATF_TC_HEAD(eventfd_badflags, tc) 730 1.2 thorpej { 731 1.2 thorpej atf_tc_set_md_var(tc, "descr", 732 1.2 thorpej "validates behavior when eventfd() called with bad flags"); 733 1.2 thorpej } 734 1.2 thorpej ATF_TC_BODY(eventfd_badflags, tc) 735 1.2 thorpej { 736 1.2 thorpej ATF_REQUIRE_ERRNO(EINVAL, 737 1.2 thorpej eventfd(0, ~(EFD_SEMAPHORE | EFD_CLOEXEC | EFD_NONBLOCK)) == -1); 738 1.2 thorpej } 739 1.2 thorpej 740 1.2 thorpej /*****************************************************************************/ 741 1.2 thorpej 742 1.2 thorpej ATF_TC(eventfd_bufsize); 743 1.2 thorpej ATF_TC_HEAD(eventfd_bufsize, tc) 744 1.2 thorpej { 745 1.2 thorpej atf_tc_set_md_var(tc, "descr", 746 1.2 thorpej "validates expected buffer size behavior"); 747 1.2 thorpej } 748 1.2 thorpej ATF_TC_BODY(eventfd_bufsize, tc) 749 1.2 thorpej { 750 1.2 thorpej eventfd_t efd_value[2]; 751 1.2 thorpej int efd; 752 1.2 thorpej 753 1.2 thorpej ATF_REQUIRE((efd = eventfd(1, EFD_NONBLOCK)) >= 0); 754 1.2 thorpej 755 1.2 thorpej ATF_REQUIRE_ERRNO(EINVAL, 756 1.2 thorpej read(efd, efd_value, sizeof(efd_value[0]) - 1) == -1); 757 1.2 thorpej 758 1.2 thorpej efd_value[0] = 0xdeadbeef; 759 1.2 thorpej efd_value[1] = 0xdeadbeef; 760 1.2 thorpej ATF_REQUIRE(read(efd, efd_value, sizeof(efd_value)) == 761 1.2 thorpej sizeof(efd_value[0])); 762 1.2 thorpej ATF_REQUIRE(efd_value[0] == 1); 763 1.2 thorpej ATF_REQUIRE(efd_value[1] == 0xdeadbeef); 764 1.2 thorpej 765 1.2 thorpej ATF_REQUIRE_ERRNO(EINVAL, 766 1.2 thorpej write(efd, efd_value, sizeof(efd_value[0]) - 1) == -1); 767 1.2 thorpej ATF_REQUIRE(write(efd, efd_value, sizeof(efd_value)) == 768 1.2 thorpej sizeof(efd_value[0])); 769 1.2 thorpej 770 1.2 thorpej ATF_REQUIRE(read(efd, efd_value, sizeof(efd_value)) == 771 1.2 thorpej sizeof(efd_value[0])); 772 1.2 thorpej ATF_REQUIRE(efd_value[0] == 1); 773 1.2 thorpej ATF_REQUIRE(efd_value[1] == 0xdeadbeef); 774 1.2 thorpej 775 1.2 thorpej (void) close(efd); 776 1.2 thorpej } 777 1.2 thorpej 778 1.2 thorpej /*****************************************************************************/ 779 1.2 thorpej 780 1.3 thorpej ATF_TC(eventfd_fcntl); 781 1.3 thorpej ATF_TC_HEAD(eventfd_fcntl, tc) 782 1.3 thorpej { 783 1.3 thorpej atf_tc_set_md_var(tc, "descr", 784 1.3 thorpej "validates fcntl behavior"); 785 1.3 thorpej } 786 1.3 thorpej ATF_TC_BODY(eventfd_fcntl, tc) 787 1.3 thorpej { 788 1.3 thorpej int efd; 789 1.3 thorpej int val; 790 1.3 thorpej 791 1.3 thorpej ATF_REQUIRE((efd = eventfd(1, 0)) >= 0); 792 1.3 thorpej ATF_REQUIRE((fcntl(efd, F_GETFL) & O_NONBLOCK) == 0); 793 1.3 thorpej ATF_REQUIRE(fcntl(efd, F_SETFL, O_NONBLOCK) == 0); 794 1.3 thorpej ATF_REQUIRE((fcntl(efd, F_GETFL) & O_NONBLOCK) != 0); 795 1.3 thorpej ATF_REQUIRE((fcntl(efd, F_GETFD) & FD_CLOEXEC) == 0); 796 1.3 thorpej 797 1.3 thorpej ATF_REQUIRE(ioctl(efd, FIONREAD, &val) == 0); 798 1.3 thorpej ATF_REQUIRE(val == sizeof(eventfd_t)); 799 1.3 thorpej 800 1.3 thorpej ATF_REQUIRE(ioctl(efd, FIONWRITE, &val) == 0); 801 1.3 thorpej ATF_REQUIRE(val == 0); 802 1.3 thorpej 803 1.3 thorpej ATF_REQUIRE_ERRNO(ENOTTY, ioctl(efd, FIONSPACE, &val) == -1); 804 1.3 thorpej (void)close(efd); 805 1.3 thorpej 806 1.3 thorpej ATF_REQUIRE((efd = eventfd(1, EFD_NONBLOCK | EFD_CLOEXEC)) >= 0); 807 1.3 thorpej ATF_REQUIRE((fcntl(efd, F_GETFL) & ~O_ACCMODE) == O_NONBLOCK); 808 1.3 thorpej ATF_REQUIRE((fcntl(efd, F_GETFD) & FD_CLOEXEC) != 0); 809 1.3 thorpej ATF_REQUIRE(fcntl(efd, F_SETFD, 0) == 0); 810 1.3 thorpej ATF_REQUIRE((fcntl(efd, F_GETFD) & FD_CLOEXEC) == 0); 811 1.3 thorpej ATF_REQUIRE(fcntl(efd, F_SETFD, FD_CLOEXEC) == 0); 812 1.3 thorpej ATF_REQUIRE((fcntl(efd, F_GETFD) & FD_CLOEXEC) != 0); 813 1.3 thorpej (void)close(efd); 814 1.3 thorpej } 815 1.3 thorpej 816 1.3 thorpej /*****************************************************************************/ 817 1.3 thorpej 818 1.2 thorpej ATF_TP_ADD_TCS(tp) 819 1.2 thorpej { 820 1.2 thorpej ATF_TP_ADD_TC(tp, eventfd_normal); 821 1.2 thorpej ATF_TP_ADD_TC(tp, eventfd_semaphore); 822 1.2 thorpej ATF_TP_ADD_TC(tp, eventfd_badflags); 823 1.2 thorpej ATF_TP_ADD_TC(tp, eventfd_bufsize); 824 1.2 thorpej ATF_TP_ADD_TC(tp, eventfd_select_poll_kevent_immed); 825 1.2 thorpej ATF_TP_ADD_TC(tp, eventfd_select_poll_kevent_block); 826 1.2 thorpej ATF_TP_ADD_TC(tp, eventfd_restart); 827 1.3 thorpej ATF_TP_ADD_TC(tp, eventfd_fcntl); 828 1.2 thorpej 829 1.2 thorpej return atf_no_error(); 830 1.2 thorpej } 831