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