Home | History | Annotate | Line # | Download | only in sys
t_futex_ops.c revision 1.5.2.1
      1 /* $NetBSD: t_futex_ops.c,v 1.5.2.1 2020/11/01 15:22:58 thorpej Exp $ */
      2 
      3 /*-
      4  * Copyright (c) 2019, 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) 2019, 2020\
     31  The NetBSD Foundation, inc. All rights reserved.");
     32 __RCSID("$NetBSD: t_futex_ops.c,v 1.5.2.1 2020/11/01 15:22:58 thorpej Exp $");
     33 
     34 #include <sys/fcntl.h>
     35 #include <sys/mman.h>
     36 #include <sys/wait.h>
     37 #include <atomic.h>
     38 #include <errno.h>
     39 #include <lwp.h>
     40 #include <stdlib.h>
     41 #include <stdio.h>
     42 #include <signal.h>
     43 #include <time.h>
     44 #include <limits.h>
     45 #include <sched.h>
     46 #include <unistd.h>
     47 
     48 #include <atf-c.h>
     49 
     50 #include <libc/include/futex_private.h>
     51 
     52 #define	LOAD(x)		(*(volatile int *)(x))
     53 #define	STORE(x, y)	*(volatile int *)(x) = (y)
     54 
     55 #if 0
     56 #define	DPRINTF(x)	printf x
     57 #else
     58 #define	DPRINTF(x)	__nothing
     59 #endif
     60 
     61 #define	STACK_SIZE	65536
     62 
     63 static volatile int futex_word;
     64 static volatile int futex_word1;
     65 
     66 static volatile unsigned int nlwps_running;
     67 
     68 struct lwp_data {
     69 	ucontext_t	context;
     70 	void		(*func)(void *);
     71 	void		*stack_base;
     72 	lwpid_t		lwpid;
     73 	pid_t		child;
     74 	lwpid_t		threadid;
     75 	int		wait_op;
     76 	int		op_flags;
     77 	int		bitset;
     78 	volatile int	*futex_ptr;
     79 	volatile int	*error_ptr;
     80 	int		block_val;
     81 	pri_t		rt_prio;
     82 
     83 	void		(*exit_func)(void);
     84 
     85 	int		futex_error;
     86 };
     87 
     88 #define	WAITER_LWP0		0
     89 #define	WAITER_LWP1		1
     90 #define	WAITER_LWP2		2
     91 #define	WAITER_LWP3		3
     92 #define	WAITER_LWP4		4
     93 #define	WAITER_LWP5		5
     94 #define	NLWPS			6
     95 
     96 struct lwp_data lwp_data[NLWPS];
     97 
     98 static const char *bs_path = "t_futex_ops_backing_store";
     99 static int bs_fd = -1;
    100 static int *bs_addr = MAP_FAILED;
    101 static void *bs_source_buffer = NULL;
    102 static void *bs_verify_buffer = NULL;
    103 static long bs_pagesize;
    104 
    105 static int pri_min;
    106 static int pri_max;
    107 
    108 static void
    109 setup_rt_params(void)
    110 {
    111 	long pri;
    112 
    113 	ATF_REQUIRE((pri = sysconf(_SC_SCHED_PRI_MIN)) != -1);
    114 	pri_min = (int)pri;
    115 	ATF_REQUIRE((pri = sysconf(_SC_SCHED_PRI_MAX)) != -1);
    116 	pri_max = (int)pri;
    117 }
    118 
    119 static void
    120 create_lwp_waiter(struct lwp_data *d)
    121 {
    122 	ATF_REQUIRE(_lwp_create(&d->context, 0, &d->lwpid) == 0);
    123 }
    124 
    125 static void
    126 exit_lwp_waiter(void)
    127 {
    128 	_lwp_exit();
    129 }
    130 
    131 static void
    132 reap_lwp_waiter(struct lwp_data *d)
    133 {
    134 	ATF_REQUIRE(_lwp_wait(d->lwpid, NULL) == 0);
    135 }
    136 
    137 static void
    138 create_proc_waiter(struct lwp_data *d)
    139 {
    140 	pid_t pid;
    141 
    142 	ATF_REQUIRE((pid = fork()) != -1);
    143 	if (pid == 0) {
    144 		(*d->func)(d);
    145 		_exit(666);		/* backstop */
    146 	} else
    147 		d->child = pid;
    148 }
    149 
    150 static void
    151 exit_proc_waiter(void)
    152 {
    153 	_exit(0);
    154 }
    155 
    156 static void
    157 reap_proc_waiter(struct lwp_data *d)
    158 {
    159 	int status;
    160 
    161 	ATF_REQUIRE(waitpid(d->child, &status, 0) == d->child);
    162 	ATF_REQUIRE(WIFEXITED(status));
    163 	ATF_REQUIRE(WEXITSTATUS(status) == 0);
    164 }
    165 
    166 static void
    167 setup_lwp_context(struct lwp_data *d, void (*func)(void *))
    168 {
    169 
    170 	memset(d, 0, sizeof(*d));
    171 	d->stack_base = mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE,
    172 	    MAP_ANON | MAP_STACK | MAP_PRIVATE, -1, 0);
    173 	ATF_REQUIRE(d->stack_base != MAP_FAILED);
    174 	_lwp_makecontext(&d->context, func, d, NULL, d->stack_base, STACK_SIZE);
    175 	d->threadid = 0;
    176 	d->func = func;
    177 }
    178 
    179 static void
    180 simple_test_waiter_lwp(void *arg)
    181 {
    182 	struct lwp_data *d = arg;
    183 
    184 	d->threadid = _lwp_self();
    185 
    186 	membar_producer();
    187 	atomic_inc_uint(&nlwps_running);
    188 	membar_sync();
    189 
    190 	if (__futex(d->futex_ptr, d->wait_op | d->op_flags,
    191 		    d->block_val, NULL, NULL, 0, d->bitset) == -1) {
    192 		d->futex_error = errno;
    193 		membar_sync();
    194 		atomic_dec_uint(&nlwps_running);
    195 		_lwp_exit();
    196 	} else {
    197 		d->futex_error = 0;
    198 	}
    199 
    200 	membar_sync();
    201 	atomic_dec_uint(&nlwps_running);
    202 
    203 	_lwp_exit();
    204 }
    205 
    206 static void
    207 rt_simple_test_waiter_lwp(void *arg)
    208 {
    209 	struct lwp_data *d = arg;
    210 	struct sched_param sp;
    211 	int policy;
    212 
    213 	d->threadid = _lwp_self();
    214 
    215 	ATF_REQUIRE(_sched_getparam(getpid(), d->threadid, &policy, &sp) == 0);
    216 	policy = SCHED_RR;
    217 	sp.sched_priority = d->rt_prio;
    218 	ATF_REQUIRE(_sched_setparam(getpid(), d->threadid, policy, &sp) == 0);
    219 
    220 	simple_test_waiter_lwp(arg);
    221 }
    222 
    223 static bool
    224 verify_zero_bs(void)
    225 {
    226 
    227 	if (bs_verify_buffer == NULL) {
    228 		bs_verify_buffer = malloc(bs_pagesize);
    229 		ATF_REQUIRE(bs_verify_buffer != NULL);
    230 	}
    231 
    232 	ATF_REQUIRE(pread(bs_fd, bs_verify_buffer,
    233 			  bs_pagesize, 0) == bs_pagesize);
    234 
    235 	return (memcmp(bs_verify_buffer, bs_source_buffer, bs_pagesize) == 0);
    236 }
    237 
    238 static void
    239 create_bs(int map_flags)
    240 {
    241 
    242 	bs_pagesize = sysconf(_SC_PAGESIZE);
    243 	ATF_REQUIRE(bs_pagesize > 0);
    244 
    245 	if ((map_flags & (MAP_FILE | MAP_ANON)) == MAP_FILE) {
    246 		bs_source_buffer = calloc(1, bs_pagesize);
    247 		ATF_REQUIRE(bs_source_buffer != NULL);
    248 
    249 		bs_fd = open(bs_path, O_RDWR | O_CREAT | O_EXCL, 0644);
    250 		ATF_REQUIRE(bs_fd != -1);
    251 
    252 		ATF_REQUIRE(pwrite(bs_fd, bs_source_buffer,
    253 				   bs_pagesize, 0) == bs_pagesize);
    254 		ATF_REQUIRE(verify_zero_bs());
    255 	}
    256 
    257 	bs_addr = mmap(NULL, bs_pagesize, PROT_READ | PROT_WRITE,
    258 		       map_flags | MAP_HASSEMAPHORE, bs_fd, 0);
    259 	ATF_REQUIRE(bs_addr != MAP_FAILED);
    260 }
    261 
    262 static void
    263 cleanup_bs(void)
    264 {
    265 
    266 	if (bs_fd != -1) {
    267 		(void) close(bs_fd);
    268 		bs_fd = -1;
    269 		(void) unlink(bs_path);
    270 	}
    271 	if (bs_source_buffer != NULL) {
    272 		free(bs_source_buffer);
    273 		bs_source_buffer = NULL;
    274 	}
    275 	if (bs_verify_buffer != NULL) {
    276 		free(bs_verify_buffer);
    277 		bs_verify_buffer = NULL;
    278 	}
    279 	if (bs_addr != MAP_FAILED) {
    280 		munmap(bs_addr, bs_pagesize);
    281 		bs_addr = MAP_FAILED;
    282 	}
    283 }
    284 
    285 static void
    286 do_cleanup(void)
    287 {
    288 	int i;
    289 
    290 	for (i = 0; i < NLWPS; i++) {
    291 		struct lwp_data *d = &lwp_data[i];
    292 		if (d->stack_base != NULL && d->stack_base != MAP_FAILED) {
    293 			(void) munmap(d->stack_base, STACK_SIZE);
    294 		}
    295 	}
    296 	memset(lwp_data, 0, sizeof(lwp_data));
    297 	STORE(&futex_word, 0);
    298 	STORE(&futex_word1, 0);
    299 	nlwps_running = 0;
    300 
    301 	cleanup_bs();
    302 }
    303 
    304 /*****************************************************************************/
    305 
    306 static void
    307 wait_wake_test_waiter_lwp(void *arg)
    308 {
    309 	struct lwp_data *d = arg;
    310 
    311 	d->threadid = _lwp_self();
    312 
    313 	STORE(d->futex_ptr, 1);
    314 	membar_sync();
    315 
    316 	/* This will block because *futex_ptr == 1. */
    317 	if (__futex(d->futex_ptr, FUTEX_WAIT | d->op_flags,
    318 		    1, NULL, NULL, 0, 0) == -1) {
    319 		STORE(d->error_ptr, errno);
    320 		(*d->exit_func)();
    321 	} else {
    322 		STORE(d->error_ptr, 0);
    323 	}
    324 
    325 	do {
    326 		membar_sync();
    327 		sleep(1);
    328 	} while (LOAD(d->futex_ptr) != 0);
    329 
    330 	STORE(d->futex_ptr, 2);
    331 	membar_sync();
    332 
    333 	do {
    334 		membar_sync();
    335 		sleep(1);
    336 	} while (LOAD(d->futex_ptr) != 3);
    337 
    338 	/* This will not block because futex_word != 666. */
    339 	if (__futex(d->futex_ptr, FUTEX_WAIT | d->op_flags,
    340 		    666, NULL, NULL, 0, 0) == -1) {
    341 		/* This SHOULD be EAGAIN. */
    342 		STORE(d->error_ptr, errno);
    343 	}
    344 
    345 	STORE(d->futex_ptr, 4);
    346 	membar_sync();
    347 
    348 	(*d->exit_func)();
    349 }
    350 
    351 static void
    352 do_futex_wait_wake_test(volatile int *futex_ptr, volatile int *error_ptr,
    353 			void (*create_func)(struct lwp_data *),
    354 			void (*exit_func)(void),
    355 			void (*reap_func)(struct lwp_data *),
    356 			int flags)
    357 {
    358 	struct lwp_data *wlwp = &lwp_data[WAITER_LWP0];
    359 	int tries;
    360 
    361 	if (error_ptr == NULL)
    362 		error_ptr = &wlwp->futex_error;
    363 
    364 	if (create_func == NULL)
    365 		create_func = create_lwp_waiter;
    366 	if (exit_func == NULL)
    367 		exit_func = exit_lwp_waiter;
    368 	if (reap_func == NULL)
    369 		reap_func = reap_lwp_waiter;
    370 
    371 	setup_lwp_context(wlwp, wait_wake_test_waiter_lwp);
    372 
    373 	DPRINTF(("futex_basic_wait_wake: testing with flags 0x%x\n", flags));
    374 	wlwp->op_flags = flags;
    375 	wlwp->error_ptr = error_ptr;
    376 	STORE(error_ptr, -1);
    377 	wlwp->futex_ptr = futex_ptr;
    378 	STORE(futex_ptr, 0);
    379 	wlwp->exit_func = exit_func;
    380 	membar_sync();
    381 
    382 	DPRINTF(("futex_basic_wait_wake: creating watier LWP\n"));
    383 	(*create_func)(wlwp);
    384 
    385 	DPRINTF(("futex_basic_wait_wake: waiting for LWP %d to enter futex\n",
    386 	    wlwp->lwpid));
    387 	for (tries = 0; tries < 5; tries++) {
    388 		membar_sync();
    389 		if (LOAD(futex_ptr) == 1)
    390 			break;
    391 		sleep(1);
    392 	}
    393 	membar_sync();
    394 	ATF_REQUIRE(LOAD(futex_ptr) == 1);
    395 
    396 	/*
    397 	 * If the LWP is blocked in the futex, it will not have yet
    398 	 * modified *error_ptr.
    399 	 */
    400 	DPRINTF(("futex_basic_wait_wake: checking for successful wait (%d)\n",
    401 	    LOAD(error_ptr)));
    402 	for (tries = 0; tries < 5; tries++) {
    403 		membar_sync();
    404 		if (LOAD(error_ptr) == -1)
    405 			break;
    406 		sleep(1);
    407 	}
    408 	membar_sync();
    409 	ATF_REQUIRE(LOAD(error_ptr) == -1);
    410 
    411 	/* Make sure invalid #wakes in rejected. */
    412 	ATF_REQUIRE_ERRNO(EINVAL,
    413 	    __futex(futex_ptr, FUTEX_WAKE | flags,
    414 		    -1, NULL, NULL, 0, 0) == -1);
    415 
    416 	DPRINTF(("futex_basic_wait_wake: waking 1 waiter\n"));
    417 	ATF_REQUIRE(__futex(futex_ptr, FUTEX_WAKE | flags,
    418 			    1, NULL, NULL, 0, 0) == 1);
    419 
    420 	DPRINTF(("futex_basic_wait_wake: checking for successful wake (%d)\n",
    421 	    LOAD(error_ptr)));
    422 	for (tries = 0; tries < 5; tries++) {
    423 		membar_sync();
    424 		if (LOAD(error_ptr) == 0)
    425 			break;
    426 		sleep(1);
    427 	}
    428 	membar_sync();
    429 	ATF_REQUIRE(LOAD(error_ptr) == 0);
    430 
    431 	STORE(futex_ptr, 0);
    432 	membar_sync();
    433 
    434 	DPRINTF(("futex_basic_wait_wake: waiting for LWP to advance (2)\n"));
    435 	for (tries = 0; tries < 5; tries++) {
    436 		membar_sync();
    437 		if (LOAD(futex_ptr) == 2)
    438 			break;
    439 		sleep(1);
    440 	}
    441 	membar_sync();
    442 	ATF_REQUIRE(LOAD(futex_ptr) == 2);
    443 
    444 	STORE(futex_ptr, 3);
    445 	membar_sync();
    446 
    447 	DPRINTF(("futex_basic_wait_wake: waiting for LWP to advance (4)\n"));
    448 	for (tries = 0; tries < 5; tries++) {
    449 		membar_sync();
    450 		if (LOAD(futex_ptr) == 4)
    451 			break;
    452 		sleep(1);
    453 	}
    454 	membar_sync();
    455 	ATF_REQUIRE(LOAD(futex_ptr) == 4);
    456 
    457 	DPRINTF(("futex_basic_wait_wake: checking for expected EGAIN\n"));
    458 	ATF_REQUIRE(LOAD(error_ptr) == EAGAIN);
    459 
    460 	DPRINTF(("futex_basic_wait_wake: reaping LWP %d\n", wlwp->lwpid));
    461 	(*reap_func)(wlwp);
    462 }
    463 
    464 ATF_TC_WITH_CLEANUP(futex_basic_wait_wake_private);
    465 ATF_TC_HEAD(futex_basic_wait_wake_private, tc)
    466 {
    467 	atf_tc_set_md_var(tc, "descr",
    468 	    "tests basic futex WAIT + WAKE operations (PRIVATE)");
    469 }
    470 ATF_TC_BODY(futex_basic_wait_wake_private, tc)
    471 {
    472 	do_futex_wait_wake_test(&futex_word, NULL,
    473 				NULL, NULL, NULL,
    474 				FUTEX_PRIVATE_FLAG);
    475 }
    476 ATF_TC_CLEANUP(futex_basic_wait_wake_private, tc)
    477 {
    478 	do_cleanup();
    479 }
    480 
    481 ATF_TC_WITH_CLEANUP(futex_basic_wait_wake_shared);
    482 ATF_TC_HEAD(futex_basic_wait_wake_shared, tc)
    483 {
    484 	atf_tc_set_md_var(tc, "descr",
    485 	    "tests basic futex WAIT + WAKE operations (SHARED)");
    486 }
    487 ATF_TC_BODY(futex_basic_wait_wake_shared, tc)
    488 {
    489 	do_futex_wait_wake_test(&futex_word, NULL,
    490 				NULL, NULL, NULL,
    491 				0);
    492 }
    493 ATF_TC_CLEANUP(futex_basic_wait_wake_shared, tc)
    494 {
    495 	do_cleanup();
    496 }
    497 
    498 ATF_TC_WITH_CLEANUP(futex_wait_wake_anon_bs_private);
    499 ATF_TC_HEAD(futex_wait_wake_anon_bs_private, tc)
    500 {
    501 	atf_tc_set_md_var(tc, "descr",
    502 	    "tests futex WAIT + WAKE operations (MAP_ANON + PRIVATE)");
    503 }
    504 ATF_TC_BODY(futex_wait_wake_anon_bs_private, tc)
    505 {
    506 	create_bs(MAP_ANON | MAP_PRIVATE);
    507 	do_futex_wait_wake_test(&bs_addr[0], NULL,
    508 				NULL, NULL, NULL,
    509 				FUTEX_PRIVATE_FLAG);
    510 }
    511 ATF_TC_CLEANUP(futex_wait_wake_anon_bs_private, tc)
    512 {
    513 	do_cleanup();
    514 }
    515 
    516 ATF_TC_WITH_CLEANUP(futex_wait_wake_anon_bs_shared);
    517 ATF_TC_HEAD(futex_wait_wake_anon_bs_shared, tc)
    518 {
    519 	atf_tc_set_md_var(tc, "descr",
    520 	    "tests futex WAIT + WAKE operations (MAP_ANON + SHARED)");
    521 }
    522 ATF_TC_BODY(futex_wait_wake_anon_bs_shared, tc)
    523 {
    524 	create_bs(MAP_ANON | MAP_PRIVATE);
    525 	do_futex_wait_wake_test(&bs_addr[0], NULL,
    526 				NULL, NULL, NULL,
    527 				0);
    528 }
    529 ATF_TC_CLEANUP(futex_wait_wake_anon_bs_shared, tc)
    530 {
    531 	do_cleanup();
    532 }
    533 
    534 ATF_TC_WITH_CLEANUP(futex_wait_wake_file_bs_private);
    535 ATF_TC_HEAD(futex_wait_wake_file_bs_private, tc)
    536 {
    537 	atf_tc_set_md_var(tc, "descr",
    538 	    "tests futex WAIT + WAKE operations (MAP_FILE + PRIVATE)");
    539 }
    540 ATF_TC_BODY(futex_wait_wake_file_bs_private, tc)
    541 {
    542 	/*
    543 	 * This combination (non-COW mapped file + PRIVATE futex)
    544 	 * doesn't really make sense, but we should make sure it
    545 	 * works as expected.
    546 	 */
    547 	create_bs(MAP_FILE | MAP_SHARED);
    548 	do_futex_wait_wake_test(&bs_addr[0], NULL,
    549 				NULL, NULL, NULL,
    550 				FUTEX_PRIVATE_FLAG);
    551 	ATF_REQUIRE(! verify_zero_bs());
    552 }
    553 ATF_TC_CLEANUP(futex_wait_wake_file_bs_private, tc)
    554 {
    555 	do_cleanup();
    556 }
    557 
    558 ATF_TC_WITH_CLEANUP(futex_wait_wake_file_bs_cow_private);
    559 ATF_TC_HEAD(futex_wait_wake_file_bs_cow_private, tc)
    560 {
    561 	atf_tc_set_md_var(tc, "descr",
    562 	    "tests futex WAIT + WAKE operations (MAP_FILE COW + PRIVATE)");
    563 }
    564 ATF_TC_BODY(futex_wait_wake_file_bs_cow_private, tc)
    565 {
    566 	create_bs(MAP_FILE | MAP_PRIVATE);
    567 	do_futex_wait_wake_test(&bs_addr[0], NULL,
    568 				NULL, NULL, NULL,
    569 				FUTEX_PRIVATE_FLAG);
    570 	ATF_REQUIRE(verify_zero_bs());
    571 }
    572 ATF_TC_CLEANUP(futex_wait_wake_file_bs_cow_private, tc)
    573 {
    574 	do_cleanup();
    575 }
    576 
    577 ATF_TC_WITH_CLEANUP(futex_wait_wake_file_bs_shared);
    578 ATF_TC_HEAD(futex_wait_wake_file_bs_shared, tc)
    579 {
    580 	atf_tc_set_md_var(tc, "descr",
    581 	    "tests futex WAIT + WAKE operations (MAP_FILE + SHARED)");
    582 }
    583 ATF_TC_BODY(futex_wait_wake_file_bs_shared, tc)
    584 {
    585 	create_bs(MAP_FILE | MAP_SHARED);
    586 	do_futex_wait_wake_test(&bs_addr[0], NULL,
    587 				NULL, NULL, NULL,
    588 				0);
    589 	ATF_REQUIRE(! verify_zero_bs());
    590 }
    591 ATF_TC_CLEANUP(futex_wait_wake_file_bs_shared, tc)
    592 {
    593 	do_cleanup();
    594 }
    595 
    596 ATF_TC_WITH_CLEANUP(futex_wait_wake_file_bs_cow_shared);
    597 ATF_TC_HEAD(futex_wait_wake_file_bs_cow_shared, tc)
    598 {
    599 	atf_tc_set_md_var(tc, "descr",
    600 	    "tests futex WAIT + WAKE operations (MAP_FILE COW + SHARED)");
    601 }
    602 ATF_TC_BODY(futex_wait_wake_file_bs_cow_shared, tc)
    603 {
    604 	/*
    605 	 * This combination (COW mapped file + SHARED futex)
    606 	 * doesn't really make sense, but we should make sure it
    607 	 * works as expected.
    608 	 */
    609 	create_bs(MAP_FILE | MAP_PRIVATE);
    610 	do_futex_wait_wake_test(&bs_addr[0], NULL,
    611 				NULL, NULL, NULL,
    612 				0);
    613 	ATF_REQUIRE(verify_zero_bs());
    614 }
    615 ATF_TC_CLEANUP(futex_wait_wake_file_bs_cow_shared, tc)
    616 {
    617 	do_cleanup();
    618 }
    619 
    620 ATF_TC_WITH_CLEANUP(futex_wait_wake_anon_bs_shared_proc);
    621 ATF_TC_HEAD(futex_wait_wake_anon_bs_shared_proc, tc)
    622 {
    623 	atf_tc_set_md_var(tc, "descr",
    624 	    "tests multiproc futex WAIT + WAKE operations (MAP_ANON + SHARED)");
    625 }
    626 ATF_TC_BODY(futex_wait_wake_anon_bs_shared_proc, tc)
    627 {
    628 	create_bs(MAP_ANON | MAP_SHARED);
    629 	do_futex_wait_wake_test(&bs_addr[0], &bs_addr[1],
    630 				create_proc_waiter,
    631 				exit_proc_waiter,
    632 				reap_proc_waiter,
    633 				0);
    634 }
    635 ATF_TC_CLEANUP(futex_wait_wake_anon_bs_shared_proc, tc)
    636 {
    637 	do_cleanup();
    638 }
    639 
    640 ATF_TC_WITH_CLEANUP(futex_wait_wake_file_bs_shared_proc);
    641 ATF_TC_HEAD(futex_wait_wake_file_bs_shared_proc, tc)
    642 {
    643 	atf_tc_set_md_var(tc, "descr",
    644 	    "tests multiproc futex WAIT + WAKE operations (MAP_ANON + SHARED)");
    645 }
    646 ATF_TC_BODY(futex_wait_wake_file_bs_shared_proc, tc)
    647 {
    648 	create_bs(MAP_FILE | MAP_SHARED);
    649 	do_futex_wait_wake_test(&bs_addr[0], &bs_addr[1],
    650 				create_proc_waiter,
    651 				exit_proc_waiter,
    652 				reap_proc_waiter,
    653 				0);
    654 }
    655 ATF_TC_CLEANUP(futex_wait_wake_file_bs_shared_proc, tc)
    656 {
    657 	do_cleanup();
    658 }
    659 
    660 /*****************************************************************************/
    661 
    662 ATF_TC(futex_wait_pointless_bitset);
    663 ATF_TC_HEAD(futex_wait_pointless_bitset, tc)
    664 {
    665 	atf_tc_set_md_var(tc, "descr",
    666 	    "tests basic futex WAIT + WAKE operations (SHARED)");
    667 }
    668 ATF_TC_BODY(futex_wait_pointless_bitset, tc)
    669 {
    670 
    671 	futex_word = 1;
    672 	ATF_REQUIRE_ERRNO(EINVAL,
    673 	    __futex(&futex_word, FUTEX_WAIT_BITSET | FUTEX_PRIVATE_FLAG,
    674 		1, NULL, NULL, 0, 0) == -1);
    675 }
    676 
    677 static void
    678 do_futex_wait_wake_bitset_test(int flags)
    679 {
    680 	struct lwp_data *wlwp0 = &lwp_data[WAITER_LWP0];
    681 	struct lwp_data *wlwp1 = &lwp_data[WAITER_LWP1];
    682 	int i, tries;
    683 
    684 	for (i = WAITER_LWP0; i <= WAITER_LWP1; i++) {
    685 		setup_lwp_context(&lwp_data[i], simple_test_waiter_lwp);
    686 		lwp_data[i].op_flags = flags;
    687 		lwp_data[i].futex_error = -1;
    688 		lwp_data[i].bitset = __BIT(i);
    689 		lwp_data[i].wait_op = FUTEX_WAIT_BITSET;
    690 		lwp_data[i].futex_ptr = &futex_word;
    691 		lwp_data[i].block_val = 1;
    692 	}
    693 
    694 	STORE(&futex_word, 1);
    695 	membar_sync();
    696 
    697 	ATF_REQUIRE(_lwp_create(&wlwp0->context, 0, &wlwp0->lwpid) == 0);
    698 	ATF_REQUIRE(_lwp_create(&wlwp1->context, 0, &wlwp1->lwpid) == 0);
    699 
    700 	for (tries = 0; tries < 5; tries++) {
    701 		membar_sync();
    702 		if (nlwps_running == 2)
    703 			break;
    704 		sleep(1);
    705 	}
    706 	membar_sync();
    707 	ATF_REQUIRE_EQ_MSG(nlwps_running, 2, "waiters failed to start");
    708 
    709 	/* Ensure they're blocked. */
    710 	ATF_REQUIRE(wlwp0->futex_error == -1);
    711 	ATF_REQUIRE(wlwp1->futex_error == -1);
    712 
    713 	/* Make sure invalid #wakes in rejected. */
    714 	ATF_REQUIRE_ERRNO(EINVAL,
    715 	    __futex(&futex_word, FUTEX_WAKE_BITSET | flags,
    716 		    -1, NULL, NULL, 0, 0) == -1);
    717 
    718 	/* This should result in no wakeups because no bits are set. */
    719 	ATF_REQUIRE(__futex(&futex_word, FUTEX_WAKE_BITSET | flags,
    720 			    INT_MAX, NULL, NULL, 0, 0) == 0);
    721 
    722 	/* This should result in no wakeups because the wrongs bits are set. */
    723 	ATF_REQUIRE(__futex(&futex_word, FUTEX_WAKE_BITSET | flags,
    724 			    INT_MAX, NULL, NULL, 0,
    725 			    ~(wlwp0->bitset | wlwp1->bitset)) == 0);
    726 
    727 	/* Trust, but verify. */
    728 	sleep(1);
    729 	for (tries = 0; tries < 5; tries++) {
    730 		membar_sync();
    731 		if (nlwps_running == 2)
    732 			break;
    733 		sleep(1);
    734 	}
    735 	membar_sync();
    736 	ATF_REQUIRE_EQ_MSG(nlwps_running, 2, "waiters exited unexpectedly");
    737 
    738 	/* Wake up the first LWP. */
    739 	ATF_REQUIRE(__futex(&futex_word, FUTEX_WAKE_BITSET | flags,
    740 			    INT_MAX, NULL, NULL, 0,
    741 			    wlwp0->bitset) == 1);
    742 	sleep(1);
    743 	for (tries = 0; tries < 5; tries++) {
    744 		membar_sync();
    745 		if (nlwps_running == 1)
    746 			break;
    747 		sleep(1);
    748 	}
    749 	membar_sync();
    750 	ATF_REQUIRE(nlwps_running == 1);
    751 	ATF_REQUIRE(wlwp0->futex_error == 0);
    752 	ATF_REQUIRE(_lwp_wait(wlwp0->lwpid, NULL) == 0);
    753 
    754 	/* Wake up the second LWP. */
    755 	ATF_REQUIRE(__futex(&futex_word, FUTEX_WAKE_BITSET | flags,
    756 			    INT_MAX, NULL, NULL, 0,
    757 			    wlwp1->bitset) == 1);
    758 	sleep(1);
    759 	for (tries = 0; tries < 5; tries++) {
    760 		membar_sync();
    761 		if (nlwps_running == 0)
    762 			break;
    763 		sleep(1);
    764 	}
    765 	membar_sync();
    766 	ATF_REQUIRE(nlwps_running == 0);
    767 	ATF_REQUIRE(wlwp1->futex_error == 0);
    768 	ATF_REQUIRE(_lwp_wait(wlwp1->lwpid, NULL) == 0);
    769 }
    770 
    771 ATF_TC_WITH_CLEANUP(futex_wait_wake_bitset);
    772 ATF_TC_HEAD(futex_wait_wake_bitset, tc)
    773 {
    774 	atf_tc_set_md_var(tc, "descr",
    775 	    "tests futex WAIT_BITSET + WAKE_BITSET operations");
    776 }
    777 ATF_TC_BODY(futex_wait_wake_bitset, tc)
    778 {
    779 	do_futex_wait_wake_bitset_test(FUTEX_PRIVATE_FLAG);
    780 }
    781 ATF_TC_CLEANUP(futex_wait_wake_bitset, tc)
    782 {
    783 	do_cleanup();
    784 }
    785 
    786 /*****************************************************************************/
    787 
    788 static void
    789 do_futex_requeue_test(int flags, int op)
    790 {
    791 	struct lwp_data *wlwp0 = &lwp_data[WAITER_LWP0];
    792 	struct lwp_data *wlwp1 = &lwp_data[WAITER_LWP1];
    793 	struct lwp_data *wlwp2 = &lwp_data[WAITER_LWP2];
    794 	struct lwp_data *wlwp3 = &lwp_data[WAITER_LWP3];
    795 	const int good_val3 = (op == FUTEX_CMP_REQUEUE) ?   1 : 0;
    796 	const int bad_val3  = (op == FUTEX_CMP_REQUEUE) ? 666 : 0;
    797 	int i, tries;
    798 
    799 	for (i = WAITER_LWP0; i <= WAITER_LWP3; i++) {
    800 		setup_lwp_context(&lwp_data[i], simple_test_waiter_lwp);
    801 		lwp_data[i].op_flags = flags;
    802 		lwp_data[i].futex_error = -1;
    803 		lwp_data[i].futex_ptr = &futex_word;
    804 		lwp_data[i].block_val = 1;
    805 		lwp_data[i].bitset = 0;
    806 		lwp_data[i].wait_op = FUTEX_WAIT;
    807 	}
    808 
    809 	STORE(&futex_word, 1);
    810 	STORE(&futex_word1, 1);
    811 	membar_sync();
    812 
    813 	ATF_REQUIRE(_lwp_create(&wlwp0->context, 0, &wlwp0->lwpid) == 0);
    814 	ATF_REQUIRE(_lwp_create(&wlwp1->context, 0, &wlwp1->lwpid) == 0);
    815 	ATF_REQUIRE(_lwp_create(&wlwp2->context, 0, &wlwp2->lwpid) == 0);
    816 	ATF_REQUIRE(_lwp_create(&wlwp3->context, 0, &wlwp3->lwpid) == 0);
    817 
    818 	for (tries = 0; tries < 5; tries++) {
    819 		membar_sync();
    820 		if (nlwps_running == 4)
    821 			break;
    822 		sleep(1);
    823 	}
    824 	membar_sync();
    825 	ATF_REQUIRE_EQ_MSG(nlwps_running, 4, "waiters failed to start");
    826 
    827 	/* Ensure they're blocked. */
    828 	ATF_REQUIRE(wlwp0->futex_error == -1);
    829 	ATF_REQUIRE(wlwp1->futex_error == -1);
    830 	ATF_REQUIRE(wlwp2->futex_error == -1);
    831 	ATF_REQUIRE(wlwp3->futex_error == -1);
    832 
    833 	/* Make sure invalid #wakes and #requeues are rejected. */
    834 	ATF_REQUIRE_ERRNO(EINVAL,
    835 	    __futex(&futex_word, op | flags,
    836 		    -1, NULL, &futex_word1, INT_MAX, bad_val3) == -1);
    837 
    838 	ATF_REQUIRE_ERRNO(EINVAL,
    839 	    __futex(&futex_word, op | flags,
    840 		    0, NULL, &futex_word1, -1, bad_val3) == -1);
    841 
    842 	/*
    843 	 * FUTEX 0: 4 LWPs
    844 	 * FUTEX 1: 0 LWPs
    845 	 */
    846 
    847 	if (op == FUTEX_CMP_REQUEUE) {
    848 		/* This should fail because the futex_word value is 1. */
    849 		ATF_REQUIRE_ERRNO(EAGAIN,
    850 		    __futex(&futex_word, op | flags,
    851 			    0, NULL, &futex_word1, INT_MAX, bad_val3) == -1);
    852 	}
    853 
    854 	/*
    855 	 * FUTEX 0: 4 LWPs
    856 	 * FUTEX 1: 0 LWPs
    857 	 */
    858 
    859 	/* Move all waiters from 0 to 1. */
    860 	ATF_REQUIRE(__futex(&futex_word, op | flags,
    861 			    0, NULL, &futex_word1, INT_MAX, good_val3) == 4);
    862 
    863 	/*
    864 	 * FUTEX 0: 0 LWPs
    865 	 * FUTEX 1: 4 LWPs
    866 	 */
    867 
    868 	if (op == FUTEX_CMP_REQUEUE) {
    869 		/* This should fail because the futex_word1 value is 1. */
    870 		ATF_REQUIRE_ERRNO(EAGAIN,
    871 		    __futex(&futex_word1, op | flags,
    872 			    1, NULL, &futex_word, 1, bad_val3) == -1);
    873 	}
    874 
    875 	/*
    876 	 * FUTEX 0: 0 LWPs
    877 	 * FUTEX 1: 4 LWPs
    878 	 */
    879 
    880 	/* Wake one waiter on 1, move one waiter to 0. */
    881 	ATF_REQUIRE(__futex(&futex_word1, op | flags,
    882 			    1, NULL, &futex_word, 1, good_val3) == 2);
    883 
    884 	/*
    885 	 * FUTEX 0: 1 LWP
    886 	 * FUTEX 1: 2 LWPs
    887 	 */
    888 
    889 	/* Wake all waiters on 0 (should be 1). */
    890 	ATF_REQUIRE(__futex(&futex_word, FUTEX_WAKE | flags,
    891 			    INT_MAX, NULL, NULL, 0, 0) == 1);
    892 
    893 	/* Wake all waiters on 1 (should be 2). */
    894 	ATF_REQUIRE(__futex(&futex_word1, FUTEX_WAKE | flags,
    895 			    INT_MAX, NULL, NULL, 0, 0) == 2);
    896 
    897 	/* Trust, but verify. */
    898 	sleep(1);
    899 	for (tries = 0; tries < 5; tries++) {
    900 		membar_sync();
    901 		if (nlwps_running == 0)
    902 			break;
    903 		sleep(1);
    904 	}
    905 	membar_sync();
    906 	ATF_REQUIRE_EQ_MSG(nlwps_running, 0, "waiters failed to exit");
    907 
    908 	ATF_REQUIRE(_lwp_wait(wlwp0->lwpid, NULL) == 0);
    909 	ATF_REQUIRE(_lwp_wait(wlwp1->lwpid, NULL) == 0);
    910 	ATF_REQUIRE(_lwp_wait(wlwp2->lwpid, NULL) == 0);
    911 	ATF_REQUIRE(_lwp_wait(wlwp3->lwpid, NULL) == 0);
    912 }
    913 
    914 ATF_TC_WITH_CLEANUP(futex_requeue);
    915 ATF_TC_HEAD(futex_requeue, tc)
    916 {
    917 	atf_tc_set_md_var(tc, "descr",
    918 	    "tests futex REQUEUE operations");
    919 }
    920 ATF_TC_BODY(futex_requeue, tc)
    921 {
    922 	do_futex_requeue_test(FUTEX_PRIVATE_FLAG, FUTEX_REQUEUE);
    923 }
    924 ATF_TC_CLEANUP(futex_requeue, tc)
    925 {
    926 	do_cleanup();
    927 }
    928 
    929 ATF_TC_WITH_CLEANUP(futex_cmp_requeue);
    930 ATF_TC_HEAD(futex_cmp_requeue, tc)
    931 {
    932 	atf_tc_set_md_var(tc, "descr",
    933 	    "tests futex CMP_REQUEUE operations");
    934 }
    935 ATF_TC_BODY(futex_cmp_requeue, tc)
    936 {
    937 	do_futex_requeue_test(FUTEX_PRIVATE_FLAG, FUTEX_CMP_REQUEUE);
    938 }
    939 ATF_TC_CLEANUP(futex_cmp_requeue, tc)
    940 {
    941 	do_cleanup();
    942 }
    943 
    944 /*****************************************************************************/
    945 
    946 static void
    947 do_futex_wake_op_op_test(int flags)
    948 {
    949 	int op;
    950 
    951 	futex_word = 0;
    952 	futex_word1 = 0;
    953 
    954 	/*
    955 	 * The op= operations should work even if there are no waiters.
    956 	 */
    957 
    958 	/*
    959 	 * Because these operations use both futex addresses, exercise
    960 	 * rejecting unaligned futex addresses here.
    961 	 */
    962 	op = FUTEX_OP(FUTEX_OP_SET, 1, FUTEX_OP_CMP_EQ, 0);
    963 	ATF_REQUIRE_ERRNO(EINVAL,
    964 	    __futex((int *)1, FUTEX_WAKE_OP | flags,
    965 		    0, NULL, &futex_word1, 0, op) == -1);
    966 	ATF_REQUIRE(futex_word1 == 0);
    967 
    968 	ATF_REQUIRE_ERRNO(EINVAL,
    969 	    __futex(&futex_word, FUTEX_WAKE_OP | flags,
    970 		    0, NULL, (int *)1, 0, op) == -1);
    971 	ATF_REQUIRE(futex_word == 0);
    972 
    973 	/* Check unmapped uaddr2 handling, too. */
    974 	ATF_REQUIRE_ERRNO(EFAULT,
    975 	    __futex(&futex_word, FUTEX_WAKE_OP | flags,
    976 		    0, NULL, NULL, 0, op) == -1);
    977 	ATF_REQUIRE(futex_word == 0);
    978 
    979 	op = FUTEX_OP(FUTEX_OP_SET, 1, FUTEX_OP_CMP_EQ, 0);
    980 	ATF_REQUIRE(__futex(&futex_word, FUTEX_WAKE_OP | flags,
    981 			    0, NULL, &futex_word1, 0, op) == 0);
    982 	ATF_REQUIRE(futex_word1 == 1);
    983 
    984 	op = FUTEX_OP(FUTEX_OP_ADD, 1, FUTEX_OP_CMP_EQ, 0);
    985 	ATF_REQUIRE(__futex(&futex_word, FUTEX_WAKE_OP | flags,
    986 			    0, NULL, &futex_word1, 0, op) == 0);
    987 	ATF_REQUIRE(futex_word1 == 2);
    988 
    989 	op = FUTEX_OP(FUTEX_OP_OR, 2, FUTEX_OP_CMP_EQ, 0);
    990 	ATF_REQUIRE(__futex(&futex_word, FUTEX_WAKE_OP | flags,
    991 			    0, NULL, &futex_word1, 0, op) == 0);
    992 	ATF_REQUIRE(futex_word1 == 2);
    993 
    994 	/* This should fail because of invalid shift value 32. */
    995 	op = FUTEX_OP(FUTEX_OP_OR | FUTEX_OP_OPARG_SHIFT, 32,
    996 		      FUTEX_OP_CMP_EQ, 0);
    997 	ATF_REQUIRE_ERRNO(EINVAL,
    998 	    __futex(&futex_word, FUTEX_WAKE_OP | flags,
    999 		    0, NULL, &futex_word1, 0, op) == -1);
   1000 	ATF_REQUIRE(futex_word1 == 2);
   1001 
   1002 	op = FUTEX_OP(FUTEX_OP_OR | FUTEX_OP_OPARG_SHIFT, 31,
   1003 		      FUTEX_OP_CMP_EQ, 0);
   1004 	ATF_REQUIRE(__futex(&futex_word, FUTEX_WAKE_OP | flags,
   1005 			    0, NULL, &futex_word1, 0, op) == 0);
   1006 	ATF_REQUIRE(futex_word1 == (int)0x80000002);
   1007 
   1008 	op = FUTEX_OP(FUTEX_OP_ANDN | FUTEX_OP_OPARG_SHIFT, 31,
   1009 		      FUTEX_OP_CMP_EQ, 0);
   1010 	ATF_REQUIRE(__futex(&futex_word, FUTEX_WAKE_OP | flags,
   1011 			    0, NULL, &futex_word1, 0, op) == 0);
   1012 	ATF_REQUIRE(futex_word1 == 2);
   1013 
   1014 	op = FUTEX_OP(FUTEX_OP_XOR, 2, FUTEX_OP_CMP_EQ, 0);
   1015 	ATF_REQUIRE(__futex(&futex_word, FUTEX_WAKE_OP | flags,
   1016 			    0, NULL, &futex_word1, 0, op) == 0);
   1017 	ATF_REQUIRE(futex_word1 == 0);
   1018 }
   1019 
   1020 ATF_TC_WITH_CLEANUP(futex_wake_op_op);
   1021 ATF_TC_HEAD(futex_wake_op_op, tc)
   1022 {
   1023 	atf_tc_set_md_var(tc, "descr",
   1024 	    "tests futex WAKE_OP OP operations");
   1025 }
   1026 ATF_TC_BODY(futex_wake_op_op, tc)
   1027 {
   1028 	do_futex_wake_op_op_test(FUTEX_PRIVATE_FLAG);
   1029 }
   1030 ATF_TC_CLEANUP(futex_wake_op_op, tc)
   1031 {
   1032 	do_cleanup();
   1033 }
   1034 
   1035 static void
   1036 create_wake_op_test_lwps(int flags)
   1037 {
   1038 	int i;
   1039 
   1040 	futex_word1 = 0;
   1041 	membar_sync();
   1042 
   1043 	for (i = WAITER_LWP0; i <= WAITER_LWP5; i++) {
   1044 		setup_lwp_context(&lwp_data[i], simple_test_waiter_lwp);
   1045 		lwp_data[i].op_flags = flags;
   1046 		lwp_data[i].futex_error = -1;
   1047 		lwp_data[i].futex_ptr = &futex_word1;
   1048 		lwp_data[i].block_val = 0;
   1049 		lwp_data[i].bitset = 0;
   1050 		lwp_data[i].wait_op = FUTEX_WAIT;
   1051 		ATF_REQUIRE(_lwp_create(&lwp_data[i].context, 0,
   1052 					&lwp_data[i].lwpid) == 0);
   1053 	}
   1054 
   1055 	for (i = 0; i < 5; i++) {
   1056 		membar_sync();
   1057 		if (nlwps_running == 6)
   1058 			break;
   1059 		sleep(1);
   1060 	}
   1061 	membar_sync();
   1062 	ATF_REQUIRE_EQ_MSG(nlwps_running, 6, "waiters failed to start");
   1063 
   1064 	/* Ensure they're blocked. */
   1065 	for (i = WAITER_LWP0; i <= WAITER_LWP5; i++) {
   1066 		ATF_REQUIRE(lwp_data[i].futex_error == -1);
   1067 	}
   1068 }
   1069 
   1070 static void
   1071 reap_wake_op_test_lwps(void)
   1072 {
   1073 	int i;
   1074 
   1075 	for (i = WAITER_LWP0; i <= WAITER_LWP5; i++) {
   1076 		ATF_REQUIRE(_lwp_wait(lwp_data[i].lwpid, NULL) == 0);
   1077 	}
   1078 }
   1079 
   1080 static void
   1081 do_futex_wake_op_cmp_test(int flags)
   1082 {
   1083 	int tries, op;
   1084 
   1085 	futex_word = 0;
   1086 	membar_sync();
   1087 
   1088 	/*
   1089 	 * Verify and negative and positive for each individual
   1090 	 * compare.
   1091 	 */
   1092 
   1093 	create_wake_op_test_lwps(flags);
   1094 
   1095 	/* #LWPs = 6 */
   1096 	op = FUTEX_OP(FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 1);
   1097 	ATF_REQUIRE(__futex(&futex_word, FUTEX_WAKE_OP | flags,
   1098 			    0, NULL, &futex_word1, 1, op) == 0);
   1099 	ATF_REQUIRE(futex_word1 == 0);
   1100 
   1101 	op = FUTEX_OP(FUTEX_OP_SET, 1, FUTEX_OP_CMP_EQ, 0);
   1102 	ATF_REQUIRE(__futex(&futex_word, FUTEX_WAKE_OP | flags,
   1103 			    0, NULL, &futex_word1, 1, op) == 1);
   1104 	ATF_REQUIRE(futex_word1 == 1);
   1105 
   1106 	/* #LWPs = 5 */
   1107 	op = FUTEX_OP(FUTEX_OP_SET, 1, FUTEX_OP_CMP_NE, 1);
   1108 	ATF_REQUIRE(__futex(&futex_word, FUTEX_WAKE_OP | flags,
   1109 			    0, NULL, &futex_word1, 1, op) == 0);
   1110 	ATF_REQUIRE(futex_word1 == 1);
   1111 
   1112 	op = FUTEX_OP(FUTEX_OP_SET, 2, FUTEX_OP_CMP_NE, 2);
   1113 	ATF_REQUIRE(__futex(&futex_word, FUTEX_WAKE_OP | flags,
   1114 			    0, NULL, &futex_word1, 1, op) == 1);
   1115 	ATF_REQUIRE(futex_word1 == 2);
   1116 
   1117 	/* #LWPs = 4 */
   1118 	op = FUTEX_OP(FUTEX_OP_SET, 2, FUTEX_OP_CMP_LT, 2);
   1119 	ATF_REQUIRE(__futex(&futex_word, FUTEX_WAKE_OP | flags,
   1120 			    0, NULL, &futex_word1, 1, op) == 0);
   1121 	ATF_REQUIRE(futex_word1 == 2);
   1122 
   1123 	op = FUTEX_OP(FUTEX_OP_SET, 2, FUTEX_OP_CMP_LT, 3);
   1124 	ATF_REQUIRE(__futex(&futex_word, FUTEX_WAKE_OP | flags,
   1125 			    0, NULL, &futex_word1, 1, op) == 1);
   1126 	ATF_REQUIRE(futex_word1 == 2);
   1127 
   1128 	/* #LWPs = 3 */
   1129 	op = FUTEX_OP(FUTEX_OP_SET, 1, FUTEX_OP_CMP_LE, 1);
   1130 	ATF_REQUIRE(__futex(&futex_word, FUTEX_WAKE_OP | flags,
   1131 			    0, NULL, &futex_word1, 1, op) == 0);
   1132 	ATF_REQUIRE(futex_word1 == 1);
   1133 
   1134 	op = FUTEX_OP(FUTEX_OP_SET, 1, FUTEX_OP_CMP_LE, 1);
   1135 	ATF_REQUIRE(__futex(&futex_word, FUTEX_WAKE_OP | flags,
   1136 			    0, NULL, &futex_word1, 1, op) == 1);
   1137 	ATF_REQUIRE(futex_word1 == 1);
   1138 
   1139 	/* #LWPs = 2 */
   1140 	op = FUTEX_OP(FUTEX_OP_SET, 3, FUTEX_OP_CMP_GT, 3);
   1141 	ATF_REQUIRE(__futex(&futex_word, FUTEX_WAKE_OP | flags,
   1142 			    0, NULL, &futex_word1, 1, op) == 0);
   1143 	ATF_REQUIRE(futex_word1 == 3);
   1144 
   1145 	op = FUTEX_OP(FUTEX_OP_SET, 2, FUTEX_OP_CMP_GT, 2);
   1146 	ATF_REQUIRE(__futex(&futex_word, FUTEX_WAKE_OP | flags,
   1147 			    0, NULL, &futex_word1, 1, op) == 1);
   1148 	ATF_REQUIRE(futex_word1 == 2);
   1149 
   1150 	/* #LWPs = 1 */
   1151 	op = FUTEX_OP(FUTEX_OP_SET, 3, FUTEX_OP_CMP_GE, 4);
   1152 	ATF_REQUIRE(__futex(&futex_word, FUTEX_WAKE_OP | flags,
   1153 			    0, NULL, &futex_word1, 1, op) == 0);
   1154 	ATF_REQUIRE(futex_word1 == 3);
   1155 
   1156 	op = FUTEX_OP(FUTEX_OP_SET, 2, FUTEX_OP_CMP_GE, 3);
   1157 	ATF_REQUIRE(__futex(&futex_word, FUTEX_WAKE_OP | flags,
   1158 			    0, NULL, &futex_word1, 1, op) == 1);
   1159 	ATF_REQUIRE(futex_word1 == 2);
   1160 
   1161 	/* #LWPs = 0 */
   1162 
   1163 	/* Trust, but verify. */
   1164 	sleep(1);
   1165 	for (tries = 0; tries < 5; tries++) {
   1166 		membar_sync();
   1167 		if (nlwps_running == 0)
   1168 			break;
   1169 		sleep(1);
   1170 	}
   1171 	membar_sync();
   1172 	ATF_REQUIRE_EQ_MSG(nlwps_running, 0, "waiters failed to exit");
   1173 
   1174 	reap_wake_op_test_lwps();
   1175 
   1176 	/*
   1177 	 * Verify wakes on uaddr work even if the uaddr2 comparison
   1178 	 * fails.
   1179 	 */
   1180 
   1181 	create_wake_op_test_lwps(flags);
   1182 
   1183 	/* #LWPs = 6 */
   1184 	ATF_REQUIRE(futex_word == 0);
   1185 	op = FUTEX_OP(FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 666);
   1186 	ATF_REQUIRE(__futex(&futex_word1, FUTEX_WAKE_OP | flags,
   1187 			    INT_MAX, NULL, &futex_word, 0, op) == 6);
   1188 	ATF_REQUIRE(futex_word == 0);
   1189 
   1190 	/* #LWPs = 0 */
   1191 
   1192 	/* Trust, but verify. */
   1193 	sleep(1);
   1194 	for (tries = 0; tries < 5; tries++) {
   1195 		membar_sync();
   1196 		if (nlwps_running == 0)
   1197 			break;
   1198 		sleep(1);
   1199 	}
   1200 	membar_sync();
   1201 	ATF_REQUIRE_EQ_MSG(nlwps_running, 0, "waiters failed to exit");
   1202 
   1203 	reap_wake_op_test_lwps();
   1204 }
   1205 
   1206 ATF_TC_WITH_CLEANUP(futex_wake_op_cmp);
   1207 ATF_TC_HEAD(futex_wake_op_cmp, tc)
   1208 {
   1209 	atf_tc_set_md_var(tc, "descr",
   1210 	    "tests futex WAKE_OP CMP operations");
   1211 }
   1212 ATF_TC_BODY(futex_wake_op_cmp, tc)
   1213 {
   1214 	do_futex_wake_op_cmp_test(FUTEX_PRIVATE_FLAG);
   1215 }
   1216 ATF_TC_CLEANUP(futex_wake_op_cmp, tc)
   1217 {
   1218 	do_cleanup();
   1219 }
   1220 
   1221 /*****************************************************************************/
   1222 
   1223 static void
   1224 do_futex_wait_timeout(bool relative, clockid_t clock)
   1225 {
   1226 	struct timespec ts;
   1227 	struct timespec deadline;
   1228 	int op = relative ? FUTEX_WAIT : FUTEX_WAIT_BITSET;
   1229 
   1230 	if (clock == CLOCK_REALTIME)
   1231 		op |= FUTEX_CLOCK_REALTIME;
   1232 
   1233 	ATF_REQUIRE(clock_gettime(clock, &deadline) == 0);
   1234 	deadline.tv_sec += 2;
   1235 	if (relative) {
   1236 		ts.tv_sec = 2;
   1237 		ts.tv_nsec = 0;
   1238 	} else {
   1239 		ts = deadline;
   1240 	}
   1241 
   1242 	futex_word = 1;
   1243 	ATF_REQUIRE_ERRNO(ETIMEDOUT,
   1244 	    __futex(&futex_word, op | FUTEX_PRIVATE_FLAG,
   1245 		    1, &ts, NULL, 0, FUTEX_BITSET_MATCH_ANY) == -1);
   1246 
   1247 	/* Can't reliably check CLOCK_REALTIME in the presence of NTP. */
   1248 	if (clock != CLOCK_REALTIME) {
   1249 		ATF_REQUIRE(clock_gettime(clock, &ts) == 0);
   1250 		ATF_REQUIRE(ts.tv_sec >= deadline.tv_sec);
   1251 		ATF_REQUIRE(ts.tv_sec > deadline.tv_sec ||
   1252 			    ts.tv_nsec >= deadline.tv_nsec);
   1253 	}
   1254 }
   1255 
   1256 ATF_TC(futex_wait_timeout_relative);
   1257 ATF_TC_HEAD(futex_wait_timeout_relative, tc)
   1258 {
   1259 	atf_tc_set_md_var(tc, "descr",
   1260 	    "tests futex WAIT with relative timeout");
   1261 }
   1262 ATF_TC_BODY(futex_wait_timeout_relative, tc)
   1263 {
   1264 	do_futex_wait_timeout(true, CLOCK_MONOTONIC);
   1265 }
   1266 
   1267 ATF_TC(futex_wait_timeout_relative_rt);
   1268 ATF_TC_HEAD(futex_wait_timeout_relative_rt, tc)
   1269 {
   1270 	atf_tc_set_md_var(tc, "descr",
   1271 	    "tests futex WAIT with relative timeout (REALTIME)");
   1272 }
   1273 ATF_TC_BODY(futex_wait_timeout_relative_rt, tc)
   1274 {
   1275 	do_futex_wait_timeout(true, CLOCK_REALTIME);
   1276 }
   1277 
   1278 ATF_TC(futex_wait_timeout_deadline);
   1279 ATF_TC_HEAD(futex_wait_timeout_deadline, tc)
   1280 {
   1281 	atf_tc_set_md_var(tc, "descr",
   1282 	    "tests futex WAIT with absolute deadline");
   1283 }
   1284 ATF_TC_BODY(futex_wait_timeout_deadline, tc)
   1285 {
   1286 	do_futex_wait_timeout(false, CLOCK_MONOTONIC);
   1287 }
   1288 
   1289 ATF_TC(futex_wait_timeout_deadline_rt);
   1290 ATF_TC_HEAD(futex_wait_timeout_deadline_rt, tc)
   1291 {
   1292 	atf_tc_set_md_var(tc, "descr",
   1293 	    "tests futex WAIT with absolute deadline (REALTIME)");
   1294 }
   1295 ATF_TC_BODY(futex_wait_timeout_deadline_rt, tc)
   1296 {
   1297 	do_futex_wait_timeout(false, CLOCK_REALTIME);
   1298 }
   1299 
   1300 /*****************************************************************************/
   1301 
   1302 static void
   1303 sig_noop(int sig __unused)
   1304 {
   1305 }
   1306 
   1307 static void (*old_act)(int) = SIG_DFL;
   1308 
   1309 static void
   1310 do_futex_wait_evil_unmapped(int map_flags)
   1311 {
   1312 	int i;
   1313 
   1314 	create_bs(map_flags);
   1315 
   1316 	old_act = signal(SIGUSR1, sig_noop);
   1317 	ATF_REQUIRE(old_act != SIG_ERR);
   1318 
   1319 	setup_lwp_context(&lwp_data[0], simple_test_waiter_lwp);
   1320 	lwp_data[0].op_flags = 0;
   1321 	lwp_data[0].futex_error = -1;
   1322 	lwp_data[0].futex_ptr = &bs_addr[0];
   1323 	lwp_data[0].block_val = 0;
   1324 	lwp_data[0].bitset = 0;
   1325 	lwp_data[0].wait_op = FUTEX_WAIT;
   1326 	ATF_REQUIRE(_lwp_create(&lwp_data[0].context, 0,
   1327 				&lwp_data[0].lwpid) == 0);
   1328 
   1329 	for (i = 0; i < 5; i++) {
   1330 		membar_sync();
   1331 		if (nlwps_running == 1)
   1332 			break;
   1333 		sleep(1);
   1334 	}
   1335 	membar_sync();
   1336 	ATF_REQUIRE_EQ_MSG(nlwps_running, 1, "waiters failed to start");
   1337 
   1338 	/* Ensure it's blocked. */
   1339 	ATF_REQUIRE(lwp_data[0].futex_error == -1);
   1340 
   1341 	/* Rudely unmap the backing store. */
   1342 	cleanup_bs();
   1343 
   1344 	/* Signal the waiter so that it leaves the futex. */
   1345 	ATF_REQUIRE(_lwp_kill(lwp_data[0].threadid, SIGUSR1) == 0);
   1346 
   1347 	/* Yay! No panic! */
   1348 
   1349 	reap_lwp_waiter(&lwp_data[0]);
   1350 }
   1351 
   1352 ATF_TC_WITH_CLEANUP(futex_wait_evil_unmapped_anon);
   1353 ATF_TC_HEAD(futex_wait_evil_unmapped_anon, tc)
   1354 {
   1355 	atf_tc_set_md_var(tc, "descr",
   1356 	    "tests futex WAIT while futex is unmapped - anon memory");
   1357 }
   1358 ATF_TC_BODY(futex_wait_evil_unmapped_anon, tc)
   1359 {
   1360 	do_futex_wait_evil_unmapped(MAP_ANON);
   1361 }
   1362 ATF_TC_CLEANUP(futex_wait_evil_unmapped_anon, tc)
   1363 {
   1364 	signal(SIGUSR1, old_act);
   1365 	do_cleanup();
   1366 }
   1367 
   1368 /*****************************************************************************/
   1369 
   1370 static void
   1371 do_test_wake_highest_pri(void)
   1372 {
   1373 	lwpid_t waiter;
   1374 	int tries;
   1375 
   1376 	setup_rt_params();
   1377 
   1378 	futex_word = 0;
   1379 	membar_sync();
   1380 
   1381 	setup_lwp_context(&lwp_data[0], rt_simple_test_waiter_lwp);
   1382 	lwp_data[0].rt_prio = pri_min;
   1383 	lwp_data[0].op_flags = FUTEX_PRIVATE_FLAG;
   1384 	lwp_data[0].futex_error = -1;
   1385 	lwp_data[0].futex_ptr = &futex_word;
   1386 	lwp_data[0].block_val = 0;
   1387 	lwp_data[0].bitset = 0;
   1388 	lwp_data[0].wait_op = FUTEX_WAIT;
   1389 	ATF_REQUIRE(_lwp_create(&lwp_data[0].context, 0,
   1390 				&lwp_data[0].lwpid) == 0);
   1391 
   1392 	for (tries = 0; tries < 5; tries++) {
   1393 		membar_sync();
   1394 		if (nlwps_running == 1)
   1395 			break;
   1396 		sleep(1);
   1397 	}
   1398 	membar_sync();
   1399 	ATF_REQUIRE_EQ_MSG(nlwps_running, 1, "lowpri waiter failed to start");
   1400 
   1401 	/* Ensure it's blocked. */
   1402 	ATF_REQUIRE(lwp_data[0].futex_error == -1);
   1403 
   1404 	setup_lwp_context(&lwp_data[1], rt_simple_test_waiter_lwp);
   1405 	lwp_data[1].rt_prio = pri_max;
   1406 	lwp_data[1].op_flags = FUTEX_PRIVATE_FLAG;
   1407 	lwp_data[1].futex_error = -1;
   1408 	lwp_data[1].futex_ptr = &futex_word;
   1409 	lwp_data[1].block_val = 0;
   1410 	lwp_data[1].bitset = 0;
   1411 	lwp_data[1].wait_op = FUTEX_WAIT;
   1412 	ATF_REQUIRE(_lwp_create(&lwp_data[1].context, 0,
   1413 				&lwp_data[1].lwpid) == 0);
   1414 
   1415 	for (tries = 0; tries < 5; tries++) {
   1416 		membar_sync();
   1417 		if (nlwps_running == 2)
   1418 			break;
   1419 		sleep(1);
   1420 	}
   1421 	membar_sync();
   1422 	ATF_REQUIRE_EQ_MSG(nlwps_running, 2, "highpri waiter failed to start");
   1423 
   1424 	/* Ensure it's blocked. */
   1425 	ATF_REQUIRE(lwp_data[1].futex_error == -1);
   1426 
   1427 	/* Wake the first LWP.  We should get the highpri thread. */
   1428 	ATF_REQUIRE(__futex(&futex_word, FUTEX_WAKE | FUTEX_PRIVATE_FLAG,
   1429 			    1, NULL, NULL, 0, 0) == 1);
   1430 	sleep(1);
   1431 	for (tries = 0; tries < 5; tries++) {
   1432 		membar_sync();
   1433 		if (nlwps_running == 1)
   1434 			break;
   1435 		sleep(1);
   1436 	}
   1437 	membar_sync();
   1438 	ATF_REQUIRE(nlwps_running == 1);
   1439 	ATF_REQUIRE(_lwp_wait(0, &waiter) == 0);
   1440 	ATF_REQUIRE(waiter == lwp_data[1].threadid);
   1441 
   1442 	/* Wake the second LWP.  We should get the lowpri thread. */
   1443 	ATF_REQUIRE(__futex(&futex_word, FUTEX_WAKE | FUTEX_PRIVATE_FLAG,
   1444 			    1, NULL, NULL, 0, 0) == 1);
   1445 	sleep(1);
   1446 	for (tries = 0; tries < 5; tries++) {
   1447 		membar_sync();
   1448 		if (nlwps_running == 0)
   1449 			break;
   1450 		sleep(1);
   1451 	}
   1452 	membar_sync();
   1453 	ATF_REQUIRE(nlwps_running == 0);
   1454 	ATF_REQUIRE(_lwp_wait(0, &waiter) == 0);
   1455 	ATF_REQUIRE(waiter == lwp_data[0].threadid);
   1456 }
   1457 
   1458 ATF_TC_WITH_CLEANUP(futex_wake_highest_pri);
   1459 ATF_TC_HEAD(futex_wake_highest_pri, tc)
   1460 {
   1461 	atf_tc_set_md_var(tc, "descr",
   1462 	    "tests that futex WAKE wakes the highest priority waiter");
   1463 	atf_tc_set_md_var(tc, "require.user", "root");
   1464 }
   1465 ATF_TC_BODY(futex_wake_highest_pri, tc)
   1466 {
   1467 	do_test_wake_highest_pri();
   1468 }
   1469 ATF_TC_CLEANUP(futex_wake_highest_pri, tc)
   1470 {
   1471 	do_cleanup();
   1472 }
   1473 
   1474 /*****************************************************************************/
   1475 
   1476 static void
   1477 do_test_rw_handoff_read(void)
   1478 {
   1479 	int i, tries;
   1480 	int rv;
   1481 
   1482 	futex_word = FUTEX_WAITERS;
   1483 	membar_sync();
   1484 
   1485 	for (i = 0; i < 3; i++) {
   1486 		setup_lwp_context(&lwp_data[i], simple_test_waiter_lwp);
   1487 		lwp_data[i].op_flags = FUTEX_PRIVATE_FLAG;
   1488 		lwp_data[i].futex_error = -1;
   1489 		lwp_data[i].futex_ptr = &futex_word;
   1490 		lwp_data[i].block_val = futex_word;
   1491 		lwp_data[i].bitset = FUTEX_RW_READER;
   1492 		lwp_data[i].wait_op = FUTEX_NETBSD_RW_WAIT;
   1493 		ATF_REQUIRE(_lwp_create(&lwp_data[i].context, 0,
   1494 					&lwp_data[i].lwpid) == 0);
   1495 	}
   1496 
   1497 	for (tries = 0; tries < 5; tries++) {
   1498 		membar_sync();
   1499 		if (nlwps_running == 3)
   1500 			break;
   1501 		sleep(1);
   1502 	}
   1503 	membar_sync();
   1504 
   1505 	ATF_REQUIRE_EQ_MSG(nlwps_running, 3, "read-waiters failed to start");
   1506 
   1507 	/* Ensure they're all blocked. */
   1508 	ATF_REQUIRE(lwp_data[0].futex_error == -1);
   1509 	ATF_REQUIRE(lwp_data[1].futex_error == -1);
   1510 	ATF_REQUIRE(lwp_data[2].futex_error == -1);
   1511 
   1512 	/* Ensure a regular wake errors out. */
   1513 	rv = __futex(&futex_word,
   1514 		     FUTEX_WAKE | FUTEX_PRIVATE_FLAG, INT_MAX, NULL,
   1515 		     NULL, 0, 0);
   1516 	ATF_REQUIRE(rv == -1 && errno == EINVAL);
   1517 
   1518 	/*
   1519 	 * Issue a hand-off.  It should wake all 3 readers and update
   1520 	 * the futex word.
   1521 	 */
   1522 	ATF_REQUIRE(__futex(&futex_word,
   1523 			    FUTEX_NETBSD_RW_HANDOFF | FUTEX_PRIVATE_FLAG,
   1524 			    FUTEX_WAITERS, NULL, NULL, 0, 0) == 3);
   1525 	ATF_REQUIRE(futex_word == 3);
   1526 
   1527 	for (tries = 0; tries < 5; tries++) {
   1528 		membar_sync();
   1529 		if (nlwps_running == 0)
   1530 			break;
   1531 		sleep(1);
   1532 	}
   1533 	membar_sync();
   1534 	ATF_REQUIRE_EQ_MSG(nlwps_running, 0, "read-waiters failed to exit");
   1535 
   1536 	/* Ensure they all exited error-free. */
   1537 	ATF_REQUIRE(lwp_data[0].futex_error == 0);
   1538 	reap_lwp_waiter(&lwp_data[0]);
   1539 
   1540 	ATF_REQUIRE(lwp_data[1].futex_error == 0);
   1541 	reap_lwp_waiter(&lwp_data[1]);
   1542 
   1543 	ATF_REQUIRE(lwp_data[2].futex_error == 0);
   1544 	reap_lwp_waiter(&lwp_data[2]);
   1545 }
   1546 
   1547 ATF_TC_WITH_CLEANUP(futex_rw_handoff_read);
   1548 ATF_TC_HEAD(futex_rw_handoff_read, tc)
   1549 {
   1550 	atf_tc_set_md_var(tc, "descr",
   1551 	    "tests rwlock direct hand-off to readers");
   1552 }
   1553 ATF_TC_BODY(futex_rw_handoff_read, tc)
   1554 {
   1555 	atf_tc_skip("futex_rw_handoff is currently broken");
   1556 	do_test_rw_handoff_read();
   1557 }
   1558 ATF_TC_CLEANUP(futex_rw_handoff_read, tc)
   1559 {
   1560 	do_cleanup();
   1561 }
   1562 
   1563 /*****************************************************************************/
   1564 
   1565 static void
   1566 do_test_rw_handoff_write(void)
   1567 {
   1568 	unsigned int i, tries;
   1569 	lwpid_t lid;
   1570 
   1571 	/*
   1572 	 * The kernel should not care about the WRITE_WANTED bit, and
   1573 	 * should use the contents of the sleepqs as the truth.
   1574 	 */
   1575 	futex_word = FUTEX_WAITERS;
   1576 	membar_sync();
   1577 
   1578 	for (i = 0; i < 3; i++) {
   1579 		setup_lwp_context(&lwp_data[i], simple_test_waiter_lwp);
   1580 		lwp_data[i].op_flags = FUTEX_PRIVATE_FLAG;
   1581 		lwp_data[i].futex_error = -1;
   1582 		lwp_data[i].futex_ptr = &futex_word;
   1583 		lwp_data[i].block_val = futex_word;
   1584 		lwp_data[i].bitset = FUTEX_RW_WRITER;
   1585 		lwp_data[i].wait_op = FUTEX_NETBSD_RW_WAIT;
   1586 		ATF_REQUIRE(_lwp_create(&lwp_data[i].context, 0,
   1587 					&lwp_data[i].lwpid) == 0);
   1588 
   1589 		/*
   1590 		 * Wait for each one to start in-turn, because we want
   1591 		 * to know the order in which the LWPs block on the futex.
   1592 		 */
   1593 		for (tries = 0; tries < 5; tries++) {
   1594 			membar_sync();
   1595 			if (nlwps_running == i + 1)
   1596 				break;
   1597 			sleep(1);
   1598 		}
   1599 		membar_sync();
   1600 	}
   1601 
   1602 	ATF_REQUIRE_EQ_MSG(nlwps_running, 3, "write-waiters failed to start");
   1603 
   1604 	/* Ensure they're all blocked. */
   1605 	ATF_REQUIRE(lwp_data[0].futex_error == -1);
   1606 	ATF_REQUIRE(lwp_data[1].futex_error == -1);
   1607 	ATF_REQUIRE(lwp_data[2].futex_error == -1);
   1608 
   1609 	/*
   1610 	 * Issue a hand-off for each waiter.  This should awaken one
   1611 	 * at a time and update the futex word.
   1612 	 */
   1613 	ATF_REQUIRE(__futex(&futex_word,
   1614 			    FUTEX_NETBSD_RW_HANDOFF | FUTEX_PRIVATE_FLAG,
   1615 			    FUTEX_WAITERS, NULL, NULL, 0, 0) == 1);
   1616 	ATF_REQUIRE(futex_word & FUTEX_RW_WRITE_LOCKED);
   1617 	ATF_REQUIRE(futex_word & FUTEX_RW_WRITE_WANTED);
   1618 	ATF_REQUIRE(futex_word & FUTEX_WAITERS);
   1619 	lid = futex_word & FUTEX_TID_MASK;
   1620 	ATF_REQUIRE(lid == lwp_data[0].lwpid);
   1621 
   1622 	ATF_REQUIRE(__futex(&futex_word,
   1623 			    FUTEX_NETBSD_RW_HANDOFF | FUTEX_PRIVATE_FLAG,
   1624 			    futex_word, NULL, NULL, 0, 0) == 1);
   1625 	ATF_REQUIRE(futex_word & FUTEX_RW_WRITE_LOCKED);
   1626 	ATF_REQUIRE(futex_word & FUTEX_RW_WRITE_WANTED);
   1627 	ATF_REQUIRE(futex_word & FUTEX_WAITERS);
   1628 	lid = futex_word & FUTEX_TID_MASK;
   1629 	ATF_REQUIRE(lid == lwp_data[1].lwpid);
   1630 
   1631 	ATF_REQUIRE(__futex(&futex_word,
   1632 			    FUTEX_NETBSD_RW_HANDOFF | FUTEX_PRIVATE_FLAG,
   1633 			    futex_word, NULL, NULL, 0, 0) == 1);
   1634 	ATF_REQUIRE(futex_word & FUTEX_RW_WRITE_LOCKED);
   1635 	ATF_REQUIRE((futex_word & FUTEX_RW_WRITE_WANTED) == 0);
   1636 	ATF_REQUIRE((futex_word & FUTEX_WAITERS) == 0);
   1637 	lid = futex_word & FUTEX_TID_MASK;
   1638 	ATF_REQUIRE(lid == lwp_data[2].lwpid);
   1639 
   1640 	/*
   1641 	 * Issue one final hand-off; it should result in a fully
   1642 	 * released lock word.
   1643 	 */
   1644 	ATF_REQUIRE(__futex(&futex_word,
   1645 			    FUTEX_NETBSD_RW_HANDOFF | FUTEX_PRIVATE_FLAG,
   1646 			    futex_word, NULL, NULL, 0, 0) == 0);
   1647 	ATF_REQUIRE(futex_word == 0);
   1648 
   1649 	for (tries = 0; tries < 5; tries++) {
   1650 		membar_sync();
   1651 		if (nlwps_running == 0)
   1652 			break;
   1653 		sleep(1);
   1654 	}
   1655 	membar_sync();
   1656 	ATF_REQUIRE_EQ_MSG(nlwps_running, 0, "read-waiters failed to exit");
   1657 
   1658 	/* Ensure they all exited error-free. */
   1659 	ATF_REQUIRE(lwp_data[0].futex_error == 0);
   1660 	reap_lwp_waiter(&lwp_data[0]);
   1661 
   1662 	ATF_REQUIRE(lwp_data[1].futex_error == 0);
   1663 	reap_lwp_waiter(&lwp_data[1]);
   1664 
   1665 	ATF_REQUIRE(lwp_data[2].futex_error == 0);
   1666 	reap_lwp_waiter(&lwp_data[2]);
   1667 }
   1668 
   1669 ATF_TC_WITH_CLEANUP(futex_rw_handoff_write);
   1670 ATF_TC_HEAD(futex_rw_handoff_write, tc)
   1671 {
   1672 	atf_tc_set_md_var(tc, "descr",
   1673 	    "tests rwlock direct hand-off to writers");
   1674 }
   1675 ATF_TC_BODY(futex_rw_handoff_write, tc)
   1676 {
   1677 	atf_tc_skip("futex_rw_handoff is currently broken");
   1678 	do_test_rw_handoff_write();
   1679 }
   1680 ATF_TC_CLEANUP(futex_rw_handoff_write, tc)
   1681 {
   1682 	do_cleanup();
   1683 }
   1684 
   1685 /*****************************************************************************/
   1686 
   1687 static void
   1688 do_test_rw_handoff_write_preferred(void)
   1689 {
   1690 	unsigned int i, tries;
   1691 	lwpid_t lid;
   1692 
   1693 	/*
   1694 	 * The kernel should not care about the WRITE_WANTED bit, and
   1695 	 * should use the contents of the sleepqs as the truth.
   1696 	 */
   1697 	futex_word = FUTEX_WAITERS;
   1698 	membar_sync();
   1699 
   1700 	for (i = 0; i < 2; i++) {
   1701 		setup_lwp_context(&lwp_data[i], simple_test_waiter_lwp);
   1702 		lwp_data[i].op_flags = FUTEX_PRIVATE_FLAG;
   1703 		lwp_data[i].futex_error = -1;
   1704 		lwp_data[i].futex_ptr = &futex_word;
   1705 		lwp_data[i].block_val = futex_word;
   1706 		lwp_data[i].bitset = FUTEX_RW_READER;
   1707 		lwp_data[i].wait_op = FUTEX_NETBSD_RW_WAIT;
   1708 		ATF_REQUIRE(_lwp_create(&lwp_data[i].context, 0,
   1709 					&lwp_data[i].lwpid) == 0);
   1710 
   1711 		/*
   1712 		 * Wait for each one to start in-turn, because we want
   1713 		 * to know the order in which the LWPs block on the futex.
   1714 		 */
   1715 		for (tries = 0; tries < 5; tries++) {
   1716 			membar_sync();
   1717 			if (nlwps_running == i + 1)
   1718 				break;
   1719 			sleep(1);
   1720 		}
   1721 		membar_sync();
   1722 	}
   1723 
   1724 	ATF_REQUIRE_EQ_MSG(nlwps_running, 2, "read-waiters failed to start");
   1725 
   1726 	setup_lwp_context(&lwp_data[2], simple_test_waiter_lwp);
   1727 	lwp_data[2].op_flags = FUTEX_PRIVATE_FLAG;
   1728 	lwp_data[2].futex_error = -1;
   1729 	lwp_data[2].futex_ptr = &futex_word;
   1730 	lwp_data[2].block_val = futex_word;
   1731 	lwp_data[2].bitset = FUTEX_RW_WRITER;
   1732 	lwp_data[2].wait_op = FUTEX_NETBSD_RW_WAIT;
   1733 	ATF_REQUIRE(_lwp_create(&lwp_data[2].context, 0,
   1734 				&lwp_data[2].lwpid) == 0);
   1735 
   1736 	for (tries = 0; tries < 5; tries++) {
   1737 		membar_sync();
   1738 		if (nlwps_running == 3)
   1739 			break;
   1740 		sleep(1);
   1741 	}
   1742 	membar_sync();
   1743 
   1744 	ATF_REQUIRE_EQ_MSG(nlwps_running, 3, "write-waiter failed to start");
   1745 
   1746 	/* Ensure they're all blocked. */
   1747 	ATF_REQUIRE(lwp_data[0].futex_error == -1);
   1748 	ATF_REQUIRE(lwp_data[1].futex_error == -1);
   1749 	ATF_REQUIRE(lwp_data[2].futex_error == -1);
   1750 
   1751 	/*
   1752 	 * Issue a hand-off.  It should select the writer despite
   1753 	 * the fact that it is the most recent waiter.
   1754 	 */
   1755 	ATF_REQUIRE(__futex(&futex_word,
   1756 			    FUTEX_NETBSD_RW_HANDOFF | FUTEX_PRIVATE_FLAG,
   1757 			    FUTEX_WAITERS, NULL, NULL, 0, 0) == 1);
   1758 	ATF_REQUIRE(futex_word & FUTEX_RW_WRITE_LOCKED);
   1759 	ATF_REQUIRE((futex_word & FUTEX_RW_WRITE_WANTED) == 0);
   1760 	ATF_REQUIRE(futex_word & FUTEX_WAITERS);
   1761 	lid = futex_word & FUTEX_TID_MASK;
   1762 	ATF_REQUIRE(lid == lwp_data[2].lwpid);
   1763 
   1764 	/*
   1765 	 * Issue another hand-off.  It should awaken both waiting
   1766 	 * readers.
   1767 	 */
   1768 	ATF_REQUIRE(__futex(&futex_word,
   1769 			    FUTEX_NETBSD_RW_HANDOFF | FUTEX_PRIVATE_FLAG,
   1770 			    futex_word, NULL, NULL, 0, 0) == 2);
   1771 	ATF_REQUIRE(futex_word == 2);
   1772 
   1773 	/*
   1774 	 * Issue one final hand-off; it should result in a fully
   1775 	 * released lock word.  Note that we don't have any
   1776 	 * outstaning waiters waiting, and therefore there will
   1777 	 * not be a kernel futex; this exercises a specific code
   1778 	 * path in the kernel designed to handle this.
   1779 	 */
   1780 	ATF_REQUIRE(__futex(&futex_word,
   1781 			    FUTEX_NETBSD_RW_HANDOFF | FUTEX_PRIVATE_FLAG,
   1782 			    futex_word, NULL, NULL, 0, 0) == 0);
   1783 	ATF_REQUIRE(futex_word == 0);
   1784 
   1785 	for (tries = 0; tries < 5; tries++) {
   1786 		membar_sync();
   1787 		if (nlwps_running == 0)
   1788 			break;
   1789 		sleep(1);
   1790 	}
   1791 	membar_sync();
   1792 	ATF_REQUIRE_EQ_MSG(nlwps_running, 0, "read-waiters failed to exit");
   1793 
   1794 	/* Ensure they all exited error-free. */
   1795 	ATF_REQUIRE(lwp_data[0].futex_error == 0);
   1796 	reap_lwp_waiter(&lwp_data[0]);
   1797 
   1798 	ATF_REQUIRE(lwp_data[1].futex_error == 0);
   1799 	reap_lwp_waiter(&lwp_data[1]);
   1800 
   1801 	ATF_REQUIRE(lwp_data[2].futex_error == 0);
   1802 	reap_lwp_waiter(&lwp_data[2]);
   1803 }
   1804 
   1805 ATF_TC_WITH_CLEANUP(futex_rw_handoff_write_preferred);
   1806 ATF_TC_HEAD(futex_rw_handoff_write_preferred, tc)
   1807 {
   1808 	atf_tc_set_md_var(tc, "descr",
   1809 	    "tests that rwlock direct hand-off prefers writers");
   1810 }
   1811 ATF_TC_BODY(futex_rw_handoff_write_preferred, tc)
   1812 {
   1813 	atf_tc_skip("futex_rw_handoff is currently broken");
   1814 	do_test_rw_handoff_write_preferred();
   1815 }
   1816 ATF_TC_CLEANUP(futex_rw_handoff_write_preferred, tc)
   1817 {
   1818 	do_cleanup();
   1819 }
   1820 
   1821 /*****************************************************************************/
   1822 
   1823 static void
   1824 do_test_rw_handoff_write_locked_rt_reader_preferred(void)
   1825 {
   1826 	unsigned int i, tries;
   1827 	lwpid_t lid;
   1828 
   1829 	setup_rt_params();
   1830 
   1831 	/*
   1832 	 * We need to show the rwlock as write-locked to ensure
   1833 	 * the rt read-waiter blocks.
   1834 	 */
   1835 	futex_word =
   1836 	    FUTEX_WAITERS | FUTEX_RW_WRITE_WANTED | FUTEX_RW_WRITE_LOCKED;
   1837 	membar_sync();
   1838 
   1839 	/*
   1840 	 * Create LWPs in the following order:
   1841 	 *
   1842 	 *	0 - non-RT reader
   1843 	 *	1 - RT reader
   1844 	 *	2 - non-RT writer
   1845 	 *
   1846 	 * We expect them to be awakened in this order:
   1847 	 *
   1848 	 *	1 -> 2 -> 0
   1849 	 */
   1850 	for (i = 0; i < 3; i++) {
   1851 		if (i == 1) {
   1852 			setup_lwp_context(&lwp_data[i],
   1853 			    rt_simple_test_waiter_lwp);
   1854 			lwp_data[i].rt_prio = pri_min;
   1855 		} else {
   1856 			setup_lwp_context(&lwp_data[i], simple_test_waiter_lwp);
   1857 		}
   1858 		lwp_data[i].op_flags = FUTEX_PRIVATE_FLAG;
   1859 		lwp_data[i].futex_error = -1;
   1860 		lwp_data[i].futex_ptr = &futex_word;
   1861 		lwp_data[i].block_val = futex_word;
   1862 		lwp_data[i].bitset = i == 2 ? FUTEX_RW_WRITER : FUTEX_RW_READER;
   1863 		lwp_data[i].wait_op = FUTEX_NETBSD_RW_WAIT;
   1864 		ATF_REQUIRE(_lwp_create(&lwp_data[i].context, 0,
   1865 					&lwp_data[i].lwpid) == 0);
   1866 
   1867 		/*
   1868 		 * Wait for each one to start in-turn, because we want
   1869 		 * to know the order in which the LWPs block on the futex.
   1870 		 */
   1871 		for (tries = 0; tries < 5; tries++) {
   1872 			membar_sync();
   1873 			if (nlwps_running == i + 1)
   1874 				break;
   1875 			sleep(1);
   1876 		}
   1877 		membar_sync();
   1878 	}
   1879 
   1880 	ATF_REQUIRE_EQ_MSG(nlwps_running, 3, "waiters failed to start");
   1881 
   1882 	/* Ensure they're all blocked. */
   1883 	ATF_REQUIRE(lwp_data[0].futex_error == -1);
   1884 	ATF_REQUIRE(lwp_data[1].futex_error == -1);
   1885 	ATF_REQUIRE(lwp_data[2].futex_error == -1);
   1886 
   1887 	/*
   1888 	 * Issue a hand-off.  It should select the RT reader, and should
   1889 	 * indicate that there are still waiters, including a write-waiter.
   1890 	 */
   1891 	ATF_REQUIRE(__futex(&futex_word,
   1892 			    FUTEX_NETBSD_RW_HANDOFF | FUTEX_PRIVATE_FLAG,
   1893 			    futex_word, NULL, NULL, 0, 0) == 1);
   1894 	ATF_REQUIRE((futex_word & FUTEX_RW_WRITE_LOCKED) == 0);
   1895 	ATF_REQUIRE(futex_word & FUTEX_RW_WRITE_WANTED);
   1896 	ATF_REQUIRE(futex_word & FUTEX_WAITERS);
   1897 	lid = futex_word & FUTEX_TID_MASK;
   1898 	ATF_REQUIRE(lid == 1);
   1899 	ATF_REQUIRE(_lwp_wait(0, &lid) == 0);
   1900 	ATF_REQUIRE(lid == lwp_data[1].lwpid);
   1901 
   1902 	/*
   1903 	 * Issue another hand-off.  It should awaken the writer and
   1904 	 * indicate only readers waiting.
   1905 	 */
   1906 	ATF_REQUIRE(__futex(&futex_word,
   1907 			    FUTEX_NETBSD_RW_HANDOFF | FUTEX_PRIVATE_FLAG,
   1908 			    futex_word, NULL, NULL, 0, 0) == 1);
   1909 	ATF_REQUIRE(futex_word & FUTEX_RW_WRITE_LOCKED);
   1910 	ATF_REQUIRE((futex_word & FUTEX_RW_WRITE_WANTED) == 0);
   1911 	ATF_REQUIRE(futex_word & FUTEX_WAITERS);
   1912 	lid = futex_word & FUTEX_TID_MASK;
   1913 	ATF_REQUIRE(lid == lwp_data[2].lwpid);
   1914 	ATF_REQUIRE(_lwp_wait(0, &lid) == 0);
   1915 	ATF_REQUIRE(lid == lwp_data[2].lwpid);
   1916 
   1917 	/*
   1918 	 * Issue another hand-off.  It would awaken the non-rt
   1919 	 * reader and indicate no waiters waiting.
   1920 	 */
   1921 	ATF_REQUIRE(__futex(&futex_word,
   1922 			    FUTEX_NETBSD_RW_HANDOFF | FUTEX_PRIVATE_FLAG,
   1923 			    futex_word, NULL, NULL, 0, 0) == 1);
   1924 	ATF_REQUIRE(futex_word == 1);
   1925 	ATF_REQUIRE(_lwp_wait(0, &lid) == 0);
   1926 	ATF_REQUIRE(lid == lwp_data[0].lwpid);
   1927 
   1928 	/*
   1929 	 * Issue one final hand-off; it should result in a fully
   1930 	 * released lock word.  Note that we don't have any
   1931 	 * outstaning waiters waiting, and therefore there will
   1932 	 * not be a kernel futex; this exercises a specific code
   1933 	 * path in the kernel designed to handle this.
   1934 	 */
   1935 	ATF_REQUIRE(__futex(&futex_word,
   1936 			    FUTEX_NETBSD_RW_HANDOFF | FUTEX_PRIVATE_FLAG,
   1937 			    futex_word, NULL, NULL, 0, 0) == 0);
   1938 	ATF_REQUIRE(futex_word == 0);
   1939 
   1940 	for (tries = 0; tries < 5; tries++) {
   1941 		membar_sync();
   1942 		if (nlwps_running == 0)
   1943 			break;
   1944 		sleep(1);
   1945 	}
   1946 	membar_sync();
   1947 	ATF_REQUIRE_EQ_MSG(nlwps_running, 0, "threads failed to exit");
   1948 
   1949 	/* Ensure they all exited error-free. */
   1950 	ATF_REQUIRE(lwp_data[0].futex_error == 0);
   1951 	ATF_REQUIRE(lwp_data[1].futex_error == 0);
   1952 	ATF_REQUIRE(lwp_data[2].futex_error == 0);
   1953 }
   1954 
   1955 ATF_TC_WITH_CLEANUP(futex_rw_handoff_write_locked_rt_reader_preferred);
   1956 ATF_TC_HEAD(futex_rw_handoff_write_locked_rt_reader_preferred, tc)
   1957 {
   1958 	atf_tc_set_md_var(tc, "descr",
   1959 	    "tests that write-locked rwlock direct hand-off "
   1960 	    "prefers rt readers over non-rt writers");
   1961 	atf_tc_set_md_var(tc, "require.user", "root");
   1962 }
   1963 ATF_TC_BODY(futex_rw_handoff_write_locked_rt_reader_preferred, tc)
   1964 {
   1965 	atf_tc_skip("futex_rw_handoff is currently broken");
   1966 	do_test_rw_handoff_write_locked_rt_reader_preferred();
   1967 }
   1968 ATF_TC_CLEANUP(futex_rw_handoff_write_locked_rt_reader_preferred, tc)
   1969 {
   1970 	do_cleanup();
   1971 }
   1972 
   1973 /*****************************************************************************/
   1974 
   1975 static void
   1976 do_test_rw_wait_write_wanted_rt_reader_preferred(void)
   1977 {
   1978 	unsigned int i, tries;
   1979 	lwpid_t lid;
   1980 
   1981 	setup_rt_params();
   1982 
   1983 	/*
   1984 	 * The kernel should not care about the WRITE_WANTED bit, and
   1985 	 * should use the contents of the sleepqs as the truth.
   1986 	 */
   1987 	futex_word = FUTEX_WAITERS;
   1988 	membar_sync();
   1989 
   1990 	/*
   1991 	 * Create LWPs in the following order:
   1992 	 *
   1993 	 *	0 - non-RT writer
   1994 	 *	1 - non-RT reader
   1995 	 *	2 - RT reader
   1996 	 *
   1997 	 * We expect:
   1998 	 *
   1999 	 * ==> non-RT reader blocks because WRITE_WANTED.
   2000 	 * ==> RT reader does not block and acquires the read-lock.
   2001 	 *
   2002 	 * We then expect hand-offs to awaken the remaining waiters
   2003 	 * in this order:
   2004 	 *
   2005 	 *	0 -> 1
   2006 	 */
   2007 	for (i = 0; i < 3; i++) {
   2008 		if (i == 2) {
   2009 			setup_lwp_context(&lwp_data[i],
   2010 			    rt_simple_test_waiter_lwp);
   2011 			lwp_data[i].rt_prio = pri_min;
   2012 		} else {
   2013 			setup_lwp_context(&lwp_data[i], simple_test_waiter_lwp);
   2014 		}
   2015 		lwp_data[i].op_flags = FUTEX_PRIVATE_FLAG;
   2016 		lwp_data[i].futex_error = -1;
   2017 		lwp_data[i].futex_ptr = &futex_word;
   2018 		lwp_data[i].block_val = futex_word;
   2019 		lwp_data[i].bitset = i == 0 ? FUTEX_RW_WRITER : FUTEX_RW_READER;
   2020 		lwp_data[i].wait_op = FUTEX_NETBSD_RW_WAIT;
   2021 		ATF_REQUIRE(_lwp_create(&lwp_data[i].context, 0,
   2022 					&lwp_data[i].lwpid) == 0);
   2023 
   2024 		/*
   2025 		 * Wait for the first 2 to start in-turn, because we want
   2026 		 * to know the order in which the LWPs block on the futex.
   2027 		 */
   2028 		for (tries = 0; i < 2 && tries < 5; tries++) {
   2029 			membar_sync();
   2030 			if (nlwps_running == i + 1)
   2031 				break;
   2032 			sleep(1);
   2033 		}
   2034 		membar_sync();
   2035 	}
   2036 
   2037 	sleep(2);
   2038 
   2039 	ATF_REQUIRE_EQ_MSG(nlwps_running, 2, "waiters failed to start");
   2040 
   2041 	/* Ensure the first two are blocked and the 3rd one succeeded. */
   2042 	ATF_REQUIRE(lwp_data[0].futex_error == -1);
   2043 	ATF_REQUIRE(lwp_data[1].futex_error == -1);
   2044 	ATF_REQUIRE(lwp_data[2].futex_error == 0);
   2045 
   2046 	/*
   2047 	 * Verify the locked-ness and waiter-status of the rwlock.
   2048 	 * Also verify it was the expected LWP that made it through
   2049 	 * the gate.
   2050 	 */
   2051 	ATF_REQUIRE(futex_word == (FUTEX_WAITERS | FUTEX_RW_WRITE_WANTED | 1));
   2052 	ATF_REQUIRE(_lwp_wait(0, &lid) == 0);
   2053 	ATF_REQUIRE(lid == lwp_data[2].lwpid);
   2054 
   2055 	/*
   2056 	 * Issue a hand-off.  It should awaken the writer and indicate only
   2057 	 * readers waiting.
   2058 	 */
   2059 	ATF_REQUIRE(__futex(&futex_word,
   2060 			    FUTEX_NETBSD_RW_HANDOFF | FUTEX_PRIVATE_FLAG,
   2061 			    futex_word, NULL, NULL, 0, 0) == 1);
   2062 	ATF_REQUIRE(futex_word & FUTEX_RW_WRITE_LOCKED);
   2063 	ATF_REQUIRE((futex_word & FUTEX_RW_WRITE_WANTED) == 0);
   2064 	ATF_REQUIRE(futex_word & FUTEX_WAITERS);
   2065 	lid = futex_word & FUTEX_TID_MASK;
   2066 	ATF_REQUIRE(lid == lwp_data[0].lwpid);
   2067 	ATF_REQUIRE(_lwp_wait(0, &lid) == 0);
   2068 	ATF_REQUIRE(lid == lwp_data[0].lwpid);
   2069 
   2070 	/*
   2071 	 * Issue another hand-off.  It would awaken the non-rt
   2072 	 * reader and indicate no waiters waiting.
   2073 	 */
   2074 	ATF_REQUIRE(__futex(&futex_word,
   2075 			    FUTEX_NETBSD_RW_HANDOFF | FUTEX_PRIVATE_FLAG,
   2076 			    futex_word, NULL, NULL, 0, 0) == 1);
   2077 	ATF_REQUIRE(futex_word == 1);
   2078 	ATF_REQUIRE(_lwp_wait(0, &lid) == 0);
   2079 	ATF_REQUIRE(lid == lwp_data[1].lwpid);
   2080 
   2081 	/*
   2082 	 * Issue one final hand-off; it should result in a fully
   2083 	 * released lock word.  Note that we don't have any
   2084 	 * outstaning waiters waiting, and therefore there will
   2085 	 * not be a kernel futex; this exercises a specific code
   2086 	 * path in the kernel designed to handle this.
   2087 	 */
   2088 	ATF_REQUIRE(__futex(&futex_word,
   2089 			    FUTEX_NETBSD_RW_HANDOFF | FUTEX_PRIVATE_FLAG,
   2090 			    futex_word, NULL, NULL, 0, 0) == 0);
   2091 	ATF_REQUIRE(futex_word == 0);
   2092 
   2093 	for (tries = 0; tries < 5; tries++) {
   2094 		membar_sync();
   2095 		if (nlwps_running == 0)
   2096 			break;
   2097 		sleep(1);
   2098 	}
   2099 	membar_sync();
   2100 	ATF_REQUIRE_EQ_MSG(nlwps_running, 0, "threads failed to exit");
   2101 
   2102 	/* Ensure they all exited error-free. */
   2103 	ATF_REQUIRE(lwp_data[0].futex_error == 0);
   2104 	ATF_REQUIRE(lwp_data[1].futex_error == 0);
   2105 }
   2106 
   2107 ATF_TC_WITH_CLEANUP(futex_rw_wait_write_wanted_rt_reader_preferred);
   2108 ATF_TC_HEAD(futex_rw_wait_write_wanted_rt_reader_preferred, tc)
   2109 {
   2110 	atf_tc_set_md_var(tc, "descr",
   2111 	    "tests that a wait by a rt-reader acquires "
   2112 	    "even if the rwlock is wanted by a non-rt writer");
   2113 	atf_tc_set_md_var(tc, "require.user", "root");
   2114 }
   2115 ATF_TC_BODY(futex_rw_wait_write_wanted_rt_reader_preferred, tc)
   2116 {
   2117 	atf_tc_skip("futex_rw_handoff is currently broken");
   2118 	do_test_rw_wait_write_wanted_rt_reader_preferred();
   2119 }
   2120 ATF_TC_CLEANUP(futex_rw_wait_write_wanted_rt_reader_preferred, tc)
   2121 {
   2122 	do_cleanup();
   2123 }
   2124 
   2125 /*****************************************************************************/
   2126 
   2127 static void
   2128 do_test_rw_handoff_rt_prio_order(void)
   2129 {
   2130 	unsigned int i, tries;
   2131 	lwpid_t lid;
   2132 
   2133 	setup_rt_params();
   2134 
   2135 	/*
   2136 	 * We need to show the rwlock as write-locked to ensure
   2137 	 * the rt read-waiter blocks.
   2138 	 */
   2139 	futex_word =
   2140 	    FUTEX_WAITERS | FUTEX_RW_WRITE_WANTED | FUTEX_RW_WRITE_LOCKED;
   2141 	membar_sync();
   2142 
   2143 	/*
   2144 	 * Create LWPs in the following order:
   2145 	 *
   2146 	 *	0 - pri_min+0 writer
   2147 	 *	1 - pri_min+1 reader
   2148 	 *	2 - pri_min+2 writer
   2149 	 *	3 - pri_min+3 reader
   2150 	 *
   2151 	 * We expect only one to be awakened at each hand-off and for them
   2152 	 * to be awakened in this order:
   2153 	 *
   2154 	 *	3 -> 2 -> 1 -> 0
   2155 	 */
   2156 	for (i = 0; i < 4; i++) {
   2157 		setup_lwp_context(&lwp_data[i], rt_simple_test_waiter_lwp);
   2158 		lwp_data[i].rt_prio = pri_min + i;
   2159 		lwp_data[i].op_flags = FUTEX_PRIVATE_FLAG;
   2160 		lwp_data[i].futex_error = -1;
   2161 		lwp_data[i].futex_ptr = &futex_word;
   2162 		lwp_data[i].block_val = futex_word;
   2163 		lwp_data[i].bitset = i & 1 ? FUTEX_RW_READER : FUTEX_RW_WRITER;
   2164 		lwp_data[i].wait_op = FUTEX_NETBSD_RW_WAIT;
   2165 		ATF_REQUIRE(_lwp_create(&lwp_data[i].context, 0,
   2166 					&lwp_data[i].lwpid) == 0);
   2167 
   2168 		/*
   2169 		 * Wait for each one to start in-turn, because we want
   2170 		 * to know the order in which the LWPs block on the futex.
   2171 		 */
   2172 		for (tries = 0; tries < 5; tries++) {
   2173 			membar_sync();
   2174 			if (nlwps_running == i + 1)
   2175 				break;
   2176 			sleep(1);
   2177 		}
   2178 		membar_sync();
   2179 	}
   2180 
   2181 	ATF_REQUIRE_EQ_MSG(nlwps_running, 4, "waiters failed to start");
   2182 
   2183 	/* Ensure they're all blocked. */
   2184 	ATF_REQUIRE(lwp_data[0].futex_error == -1);
   2185 	ATF_REQUIRE(lwp_data[1].futex_error == -1);
   2186 	ATF_REQUIRE(lwp_data[2].futex_error == -1);
   2187 	ATF_REQUIRE(lwp_data[3].futex_error == -1);
   2188 
   2189 	/*
   2190 	 * Issue a hand-off.  It should select the pri_min+3 reader, and should
   2191 	 * indicate that there are still waiters, including a write-waiter.
   2192 	 */
   2193 	ATF_REQUIRE(__futex(&futex_word,
   2194 			    FUTEX_NETBSD_RW_HANDOFF | FUTEX_PRIVATE_FLAG,
   2195 			    futex_word, NULL, NULL, 0, 0) == 1);
   2196 	ATF_REQUIRE((futex_word & FUTEX_RW_WRITE_LOCKED) == 0);
   2197 	ATF_REQUIRE(futex_word & FUTEX_RW_WRITE_WANTED);
   2198 	ATF_REQUIRE(futex_word & FUTEX_WAITERS);
   2199 	lid = futex_word & FUTEX_TID_MASK;
   2200 	ATF_REQUIRE(lid == 1);
   2201 	ATF_REQUIRE(_lwp_wait(0, &lid) == 0);
   2202 	ATF_REQUIRE(lid == lwp_data[3].lwpid);
   2203 
   2204 	/*
   2205 	 * Issue another hand-off.  It should awaken the pri_min+2 writer and
   2206 	 * indicate that there are still waiters, including a write-waiter.
   2207 	 */
   2208 	ATF_REQUIRE(__futex(&futex_word,
   2209 			    FUTEX_NETBSD_RW_HANDOFF | FUTEX_PRIVATE_FLAG,
   2210 			    futex_word, NULL, NULL, 0, 0) == 1);
   2211 	ATF_REQUIRE(futex_word & FUTEX_RW_WRITE_LOCKED);
   2212 	ATF_REQUIRE(futex_word & FUTEX_RW_WRITE_WANTED);
   2213 	ATF_REQUIRE(futex_word & FUTEX_WAITERS);
   2214 	lid = futex_word & FUTEX_TID_MASK;
   2215 	ATF_REQUIRE(lid == lwp_data[2].lwpid);
   2216 	ATF_REQUIRE(_lwp_wait(0, &lid) == 0);
   2217 	ATF_REQUIRE(lid == lwp_data[2].lwpid);
   2218 
   2219 	/*
   2220 	 * Issue another a hand-off.  It should select the pri_min+1 reader,
   2221 	 * and should indicate that there are still waiters, including a
   2222 	 * write-waiter.
   2223 	 */
   2224 	ATF_REQUIRE(__futex(&futex_word,
   2225 			    FUTEX_NETBSD_RW_HANDOFF | FUTEX_PRIVATE_FLAG,
   2226 			    futex_word, NULL, NULL, 0, 0) == 1);
   2227 	ATF_REQUIRE((futex_word & FUTEX_RW_WRITE_LOCKED) == 0);
   2228 	ATF_REQUIRE(futex_word & FUTEX_RW_WRITE_WANTED);
   2229 	ATF_REQUIRE(futex_word & FUTEX_WAITERS);
   2230 	lid = futex_word & FUTEX_TID_MASK;
   2231 	ATF_REQUIRE(lid == 1);
   2232 	ATF_REQUIRE(_lwp_wait(0, &lid) == 0);
   2233 	ATF_REQUIRE(lid == lwp_data[1].lwpid);
   2234 
   2235 	/*
   2236 	 * Issue another hand-off.  It should awaken the pri_min+0 writer and
   2237 	 * indicate that there are no more waiters.
   2238 	 */
   2239 	ATF_REQUIRE(__futex(&futex_word,
   2240 			    FUTEX_NETBSD_RW_HANDOFF | FUTEX_PRIVATE_FLAG,
   2241 			    futex_word, NULL, NULL, 0, 0) == 1);
   2242 	ATF_REQUIRE(futex_word & FUTEX_RW_WRITE_LOCKED);
   2243 	ATF_REQUIRE((futex_word & FUTEX_RW_WRITE_WANTED) == 0);
   2244 	ATF_REQUIRE((futex_word & FUTEX_WAITERS) == 0);
   2245 	lid = futex_word & FUTEX_TID_MASK;
   2246 	ATF_REQUIRE(lid == lwp_data[0].lwpid);
   2247 	ATF_REQUIRE(_lwp_wait(0, &lid) == 0);
   2248 	ATF_REQUIRE(lid == lwp_data[0].lwpid);
   2249 
   2250 	/*
   2251 	 * Issue one final hand-off; it should result in a fully
   2252 	 * released lock word.  Note that we don't have any
   2253 	 * outstaning waiters waiting, and therefore there will
   2254 	 * not be a kernel futex; this exercises a specific code
   2255 	 * path in the kernel designed to handle this.
   2256 	 */
   2257 	ATF_REQUIRE(__futex(&futex_word,
   2258 			    FUTEX_NETBSD_RW_HANDOFF | FUTEX_PRIVATE_FLAG,
   2259 			    futex_word, NULL, NULL, 0, 0) == 0);
   2260 	ATF_REQUIRE(futex_word == 0);
   2261 
   2262 	for (tries = 0; tries < 5; tries++) {
   2263 		membar_sync();
   2264 		if (nlwps_running == 0)
   2265 			break;
   2266 		sleep(1);
   2267 	}
   2268 	membar_sync();
   2269 	ATF_REQUIRE_EQ_MSG(nlwps_running, 0, "threads failed to exit");
   2270 
   2271 	/* Ensure they all exited error-free. */
   2272 	ATF_REQUIRE(lwp_data[0].futex_error == 0);
   2273 	ATF_REQUIRE(lwp_data[1].futex_error == 0);
   2274 	ATF_REQUIRE(lwp_data[2].futex_error == 0);
   2275 	ATF_REQUIRE(lwp_data[3].futex_error == 0);
   2276 }
   2277 
   2278 ATF_TC_WITH_CLEANUP(futex_rw_handoff_rt_prio_order);
   2279 ATF_TC_HEAD(futex_rw_handoff_rt_prio_order, tc)
   2280 {
   2281 	atf_tc_set_md_var(tc, "descr",
   2282 	    "tests that hand-off to mixed readers/writer occurs "
   2283 	    "in strict priority order");
   2284 	atf_tc_set_md_var(tc, "require.user", "root");
   2285 }
   2286 ATF_TC_BODY(futex_rw_handoff_rt_prio_order, tc)
   2287 {
   2288 	atf_tc_skip("futex_rw_handoff is currently broken");
   2289 	do_test_rw_handoff_rt_prio_order();
   2290 }
   2291 ATF_TC_CLEANUP(futex_rw_handoff_rt_prio_order, tc)
   2292 {
   2293 	do_cleanup();
   2294 }
   2295 
   2296 /*****************************************************************************/
   2297 
   2298 ATF_TP_ADD_TCS(tp)
   2299 {
   2300 	ATF_TP_ADD_TC(tp, futex_basic_wait_wake_private);
   2301 	ATF_TP_ADD_TC(tp, futex_basic_wait_wake_shared);
   2302 	ATF_TP_ADD_TC(tp, futex_wait_wake_anon_bs_private);
   2303 	ATF_TP_ADD_TC(tp, futex_wait_wake_anon_bs_shared);
   2304 	ATF_TP_ADD_TC(tp, futex_wait_wake_file_bs_private);
   2305 	ATF_TP_ADD_TC(tp, futex_wait_wake_file_bs_shared);
   2306 	ATF_TP_ADD_TC(tp, futex_wait_wake_file_bs_cow_private);
   2307 	ATF_TP_ADD_TC(tp, futex_wait_wake_file_bs_cow_shared);
   2308 
   2309 	ATF_TP_ADD_TC(tp, futex_wait_wake_anon_bs_shared_proc);
   2310 	ATF_TP_ADD_TC(tp, futex_wait_wake_file_bs_shared_proc);
   2311 
   2312 	ATF_TP_ADD_TC(tp, futex_wait_pointless_bitset);
   2313 	ATF_TP_ADD_TC(tp, futex_wait_wake_bitset);
   2314 
   2315 	ATF_TP_ADD_TC(tp, futex_wait_timeout_relative);
   2316 	ATF_TP_ADD_TC(tp, futex_wait_timeout_relative_rt);
   2317 	ATF_TP_ADD_TC(tp, futex_wait_timeout_deadline);
   2318 	ATF_TP_ADD_TC(tp, futex_wait_timeout_deadline_rt);
   2319 
   2320 	ATF_TP_ADD_TC(tp, futex_wait_evil_unmapped_anon);
   2321 
   2322 	ATF_TP_ADD_TC(tp, futex_requeue);
   2323 	ATF_TP_ADD_TC(tp, futex_cmp_requeue);
   2324 
   2325 	ATF_TP_ADD_TC(tp, futex_wake_op_op);
   2326 	ATF_TP_ADD_TC(tp, futex_wake_op_cmp);
   2327 
   2328 	ATF_TP_ADD_TC(tp, futex_wake_highest_pri);
   2329 
   2330 	ATF_TP_ADD_TC(tp, futex_rw_handoff_read);
   2331 	ATF_TP_ADD_TC(tp, futex_rw_handoff_write);
   2332 	ATF_TP_ADD_TC(tp, futex_rw_handoff_write_preferred);
   2333 	ATF_TP_ADD_TC(tp, futex_rw_handoff_write_locked_rt_reader_preferred);
   2334 	ATF_TP_ADD_TC(tp, futex_rw_wait_write_wanted_rt_reader_preferred);
   2335 	ATF_TP_ADD_TC(tp, futex_rw_handoff_rt_prio_order);
   2336 
   2337 	return atf_no_error();
   2338 }
   2339