Home | History | Annotate | Line # | Download | only in libpthread
t_mutex.c revision 1.9.2.5
      1 /* $NetBSD: t_mutex.c,v 1.9.2.5 2017/04/26 02:53:33 pgoyette Exp $ */
      2 
      3 /*
      4  * Copyright (c) 2008 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) 2008\
     31  The NetBSD Foundation, inc. All rights reserved.");
     32 __RCSID("$NetBSD: t_mutex.c,v 1.9.2.5 2017/04/26 02:53:33 pgoyette Exp $");
     33 
     34 #include <sys/time.h> /* For timespecadd */
     35 #include <inttypes.h> /* For UINT16_MAX */
     36 #include <pthread.h>
     37 #include <stdio.h>
     38 #include <string.h>
     39 #include <errno.h>
     40 #include <time.h>
     41 #include <unistd.h>
     42 #include <sys/sched.h>
     43 #include <sys/param.h>
     44 
     45 #include <atf-c.h>
     46 
     47 #include "h_common.h"
     48 
     49 static pthread_mutex_t mutex;
     50 static pthread_mutex_t static_mutex = PTHREAD_MUTEX_INITIALIZER;
     51 static int global_x;
     52 
     53 #ifdef TIMEDMUTEX
     54 /* This code is used for verifying non-timed specific code */
     55 static struct timespec ts_lengthy = {
     56 	.tv_sec = UINT16_MAX,
     57 	.tv_nsec = 0
     58 };
     59 /* This code is used for verifying timed-only specific code */
     60 static struct timespec ts_shortlived = {
     61 	.tv_sec = 0,
     62 	.tv_nsec = 120
     63 };
     64 
     65 static int
     66 mutex_lock(pthread_mutex_t *m, const struct timespec *ts)
     67 {
     68 	struct timespec ts_wait;
     69 	ATF_REQUIRE(clock_gettime(CLOCK_REALTIME, &ts_wait) != -1);
     70 	timespecadd(&ts_wait, ts, &ts_wait);
     71 
     72 	return pthread_mutex_timedlock(m, &ts_wait);
     73 }
     74 #else
     75 #define mutex_lock(a, b) pthread_mutex_lock(a)
     76 #endif
     77 
     78 static void *
     79 mutex1_threadfunc(void *arg)
     80 {
     81 	int *param;
     82 
     83 	printf("2: Second thread.\n");
     84 
     85 	param = arg;
     86 	printf("2: Locking mutex\n");
     87 	mutex_lock(&mutex, &ts_lengthy);
     88 	printf("2: Got mutex. *param = %d\n", *param);
     89 	ATF_REQUIRE_EQ(*param, 20);
     90 	(*param)++;
     91 
     92 	pthread_mutex_unlock(&mutex);
     93 
     94 	return param;
     95 }
     96 
     97 ATF_TC(mutex1);
     98 ATF_TC_HEAD(mutex1, tc)
     99 {
    100 	atf_tc_set_md_var(tc, "descr", "Checks mutexes");
    101 }
    102 ATF_TC_BODY(mutex1, tc)
    103 {
    104 	int x;
    105 	pthread_t new;
    106 	void *joinval;
    107 
    108 	printf("1: Mutex-test 1\n");
    109 
    110 	PTHREAD_REQUIRE(pthread_mutex_init(&mutex, NULL));
    111 	x = 1;
    112 	PTHREAD_REQUIRE(mutex_lock(&mutex, &ts_lengthy));
    113 	PTHREAD_REQUIRE(pthread_create(&new, NULL, mutex1_threadfunc, &x));
    114 	printf("1: Before changing the value.\n");
    115 	sleep(2);
    116 	x = 20;
    117 	printf("1: Before releasing the mutex.\n");
    118 	sleep(2);
    119 	PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
    120 	printf("1: After releasing the mutex.\n");
    121 	PTHREAD_REQUIRE(pthread_join(new, &joinval));
    122 
    123 	PTHREAD_REQUIRE(mutex_lock(&mutex, &ts_lengthy));
    124 	printf("1: Thread joined. X was %d. Return value (int) was %d\n",
    125 		x, *(int *)joinval);
    126 	ATF_REQUIRE_EQ(x, 21);
    127 	ATF_REQUIRE_EQ(*(int *)joinval, 21);
    128 	PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
    129 }
    130 
    131 static void *
    132 mutex2_threadfunc(void *arg)
    133 {
    134 	long count = *(int *)arg;
    135 
    136 	printf("2: Second thread (%p). Count is %ld\n", pthread_self(), count);
    137 
    138 	while (count--) {
    139 		PTHREAD_REQUIRE(mutex_lock(&mutex, &ts_lengthy));
    140 		global_x++;
    141 		PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
    142 	}
    143 
    144 	return (void *)count;
    145 }
    146 
    147 ATF_TC(mutex2);
    148 ATF_TC_HEAD(mutex2, tc)
    149 {
    150 	atf_tc_set_md_var(tc, "descr", "Checks mutexes");
    151 }
    152 ATF_TC_BODY(mutex2, tc)
    153 {
    154 	int count, count2;
    155 	pthread_t new;
    156 	void *joinval;
    157 
    158 	printf("1: Mutex-test 2\n");
    159 
    160 	PTHREAD_REQUIRE(pthread_mutex_init(&mutex, NULL));
    161 
    162 	global_x = 0;
    163 	count = count2 = 10000000;
    164 
    165 	PTHREAD_REQUIRE(mutex_lock(&mutex, &ts_lengthy));
    166 	PTHREAD_REQUIRE(pthread_create(&new, NULL, mutex2_threadfunc, &count2));
    167 
    168 	printf("1: Thread %p\n", pthread_self());
    169 
    170 	PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
    171 
    172 	while (count--) {
    173 		PTHREAD_REQUIRE(mutex_lock(&mutex, &ts_lengthy));
    174 		global_x++;
    175 		PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
    176 	}
    177 
    178 	PTHREAD_REQUIRE(pthread_join(new, &joinval));
    179 
    180 	PTHREAD_REQUIRE(mutex_lock(&mutex, &ts_lengthy));
    181 	printf("1: Thread joined. X was %d. Return value (long) was %ld\n",
    182 		global_x, (long)joinval);
    183 	ATF_REQUIRE_EQ(global_x, 20000000);
    184 }
    185 
    186 static void *
    187 mutex3_threadfunc(void *arg)
    188 {
    189 	long count = *(int *)arg;
    190 
    191 	printf("2: Second thread (%p). Count is %ld\n", pthread_self(), count);
    192 
    193 	while (count--) {
    194 		PTHREAD_REQUIRE(mutex_lock(&static_mutex, &ts_lengthy));
    195 		global_x++;
    196 		PTHREAD_REQUIRE(pthread_mutex_unlock(&static_mutex));
    197 	}
    198 
    199 	return (void *)count;
    200 }
    201 
    202 ATF_TC(mutex3);
    203 ATF_TC_HEAD(mutex3, tc)
    204 {
    205 	atf_tc_set_md_var(tc, "descr", "Checks mutexes using a static "
    206 	    "initializer");
    207 }
    208 ATF_TC_BODY(mutex3, tc)
    209 {
    210 	int count, count2;
    211 	pthread_t new;
    212 	void *joinval;
    213 
    214 	printf("1: Mutex-test 3\n");
    215 
    216 	global_x = 0;
    217 	count = count2 = 10000000;
    218 
    219 	PTHREAD_REQUIRE(mutex_lock(&static_mutex, &ts_lengthy));
    220 	PTHREAD_REQUIRE(pthread_create(&new, NULL, mutex3_threadfunc, &count2));
    221 
    222 	printf("1: Thread %p\n", pthread_self());
    223 
    224 	PTHREAD_REQUIRE(pthread_mutex_unlock(&static_mutex));
    225 
    226 	while (count--) {
    227 		PTHREAD_REQUIRE(mutex_lock(&static_mutex, &ts_lengthy));
    228 		global_x++;
    229 		PTHREAD_REQUIRE(pthread_mutex_unlock(&static_mutex));
    230 	}
    231 
    232 	PTHREAD_REQUIRE(pthread_join(new, &joinval));
    233 
    234 	PTHREAD_REQUIRE(mutex_lock(&static_mutex, &ts_lengthy));
    235 	printf("1: Thread joined. X was %d. Return value (long) was %ld\n",
    236 		global_x, (long)joinval);
    237 	ATF_REQUIRE_EQ(global_x, 20000000);
    238 }
    239 
    240 static void *
    241 mutex4_threadfunc(void *arg)
    242 {
    243 	int *param;
    244 
    245 	printf("2: Second thread.\n");
    246 
    247 	param = arg;
    248 	printf("2: Locking mutex\n");
    249 	PTHREAD_REQUIRE(mutex_lock(&mutex, &ts_lengthy));
    250 	printf("2: Got mutex. *param = %d\n", *param);
    251 	(*param)++;
    252 
    253 	PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
    254 
    255 	return param;
    256 }
    257 
    258 ATF_TC(mutex4);
    259 ATF_TC_HEAD(mutex4, tc)
    260 {
    261 	atf_tc_set_md_var(tc, "descr", "Checks mutexes");
    262 }
    263 ATF_TC_BODY(mutex4, tc)
    264 {
    265 	int x;
    266 	pthread_t new;
    267 	pthread_mutexattr_t mattr;
    268 	void *joinval;
    269 
    270 	printf("1: Mutex-test 4\n");
    271 
    272 	PTHREAD_REQUIRE(pthread_mutexattr_init(&mattr));
    273 	PTHREAD_REQUIRE(pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_RECURSIVE));
    274 
    275 	PTHREAD_REQUIRE(pthread_mutex_init(&mutex, &mattr));
    276 
    277 	PTHREAD_REQUIRE(pthread_mutexattr_destroy(&mattr));
    278 
    279 	x = 1;
    280 	PTHREAD_REQUIRE(mutex_lock(&mutex, &ts_lengthy));
    281 	PTHREAD_REQUIRE(pthread_create(&new, NULL, mutex4_threadfunc, &x));
    282 
    283 	printf("1: Before recursively acquiring the mutex.\n");
    284 	PTHREAD_REQUIRE(mutex_lock(&mutex, &ts_lengthy));
    285 
    286 	printf("1: Before releasing the mutex once.\n");
    287 	sleep(2);
    288 	PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
    289 	printf("1: After releasing the mutex once.\n");
    290 
    291 	x = 20;
    292 
    293 	printf("1: Before releasing the mutex twice.\n");
    294 	sleep(2);
    295 	PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
    296 	printf("1: After releasing the mutex twice.\n");
    297 
    298 	PTHREAD_REQUIRE(pthread_join(new, &joinval));
    299 
    300 	PTHREAD_REQUIRE(mutex_lock(&mutex, &ts_lengthy));
    301 	printf("1: Thread joined. X was %d. Return value (int) was %d\n",
    302 		x, *(int *)joinval);
    303 	ATF_REQUIRE_EQ(x, 21);
    304 	ATF_REQUIRE_EQ(*(int *)joinval, 21);
    305 	PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
    306 }
    307 
    308 static pthread_mutexattr_t attr5;
    309 static pthread_mutex_t mutex5;
    310 static int min_fifo_prio, max_fifo_prio;
    311 
    312 static void *
    313 child_func(void* arg)
    314 {
    315 	int res;
    316 
    317 	printf("child is waiting\n");
    318 	res = _sched_protect(-2);
    319 	ATF_REQUIRE_EQ_MSG(res, -1, "sched_protect returned %d", res);
    320 	ATF_REQUIRE_EQ(errno, ENOENT);
    321 	PTHREAD_REQUIRE(mutex_lock(&mutex5, &ts_lengthy));
    322 	printf("child is owning resource\n");
    323 	res = _sched_protect(-2);
    324 	ATF_REQUIRE_EQ(res,  max_fifo_prio);
    325 	PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex5));
    326 	printf("child is done\n");
    327 
    328 	return 0;
    329 }
    330 
    331 ATF_TC(mutex5);
    332 ATF_TC_HEAD(mutex5, tc)
    333 {
    334 	atf_tc_set_md_var(tc, "descr", "Checks mutexes for priority setting");
    335 	atf_tc_set_md_var(tc, "require.user", "root");
    336 }
    337 
    338 ATF_TC_BODY(mutex5, tc)
    339 {
    340 	int res;
    341 	struct sched_param param;
    342 	pthread_t child;
    343 
    344 	min_fifo_prio = sched_get_priority_min(SCHED_FIFO);
    345 	max_fifo_prio = sched_get_priority_max(SCHED_FIFO);
    346 	printf("min prio for FIFO = %d\n", min_fifo_prio);
    347 	param.sched_priority = min_fifo_prio;
    348 
    349 	/* = 0 OTHER, 1 FIFO, 2 RR, -1 NONE */
    350 	res = sched_setscheduler(getpid(), SCHED_FIFO, &param);
    351 	printf("previous policy used = %d\n", res);
    352 
    353 	res = sched_getscheduler(getpid());
    354 	ATF_REQUIRE_EQ_MSG(res, SCHED_FIFO, "sched %d != FIFO %d", res,
    355 	    SCHED_FIFO);
    356 
    357 	PTHREAD_REQUIRE(pthread_mutexattr_init(&attr5));
    358 	PTHREAD_REQUIRE(pthread_mutexattr_setprotocol(&attr5,
    359 	    PTHREAD_PRIO_PROTECT));
    360 	PTHREAD_REQUIRE(pthread_mutexattr_setprioceiling(&attr5,
    361 	    max_fifo_prio));
    362 
    363 	PTHREAD_REQUIRE(pthread_mutex_init(&mutex5, &attr5));
    364 	PTHREAD_REQUIRE(mutex_lock(&mutex5, &ts_lengthy));
    365 	printf("enter critical section for main\n");
    366 	PTHREAD_REQUIRE(pthread_create(&child, NULL, child_func, NULL));
    367 	printf("main starts to sleep\n");
    368 	sleep(10);
    369 	printf("main completes\n");
    370 	PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex5));
    371 	PTHREAD_REQUIRE(pthread_join(child, NULL));
    372 }
    373 
    374 static int start = 0;
    375 static uintmax_t high_cnt = 0, low_cnt = 0, MAX_LOOP = 100000000;
    376 
    377 static void *
    378 high_prio(void* arg)
    379 {
    380 	struct sched_param param;
    381 	int policy;
    382 	param.sched_priority = min_fifo_prio + 10;
    383 	pthread_t childid = pthread_self();
    384 
    385 	PTHREAD_REQUIRE(pthread_setschedparam(childid, 1, &param));
    386 	PTHREAD_REQUIRE(pthread_getschedparam(childid, &policy, &param));
    387 	printf("high protect = %d, prio = %d\n",
    388 	    _sched_protect(-2), param.sched_priority);
    389 	ATF_REQUIRE_EQ(policy, 1);
    390 	printf("high prio = %d\n", param.sched_priority);
    391 	sleep(1);
    392 	long tmp = 0;
    393 	for (int i = 0; i < 20; i++) {
    394 		while (high_cnt < MAX_LOOP) {
    395 			tmp += (123456789 % 1234) * (987654321 % 54321);
    396 			high_cnt += 1;
    397 		}
    398 		high_cnt = 0;
    399 		sleep(1);
    400 	}
    401 	PTHREAD_REQUIRE(mutex_lock(&mutex, &ts_lengthy));
    402 	if (start == 0) start = 2;
    403 	PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
    404 
    405 	return 0;
    406 }
    407 
    408 static void *
    409 low_prio(void* arg)
    410 {
    411 	struct sched_param param;
    412 	int policy;
    413 	param.sched_priority = min_fifo_prio;
    414 	pthread_t childid = pthread_self();
    415 	int res = _sched_protect(max_fifo_prio);
    416 	ATF_REQUIRE_EQ(res, 0);
    417 	PTHREAD_REQUIRE(pthread_setschedparam(childid, 1, &param));
    418 	PTHREAD_REQUIRE(pthread_getschedparam(childid, &policy, &param));
    419 	printf("low protect = %d, prio = %d\n", _sched_protect(-2),
    420 	    param.sched_priority);
    421 	ATF_REQUIRE_EQ(policy, 1);
    422 	printf("low prio = %d\n", param.sched_priority);
    423 	sleep(1);
    424 	long tmp = 0;
    425 	for (int i = 0; i < 20; i++) {
    426 		while (low_cnt < MAX_LOOP) {
    427 			tmp += (123456789 % 1234) * (987654321 % 54321);
    428 			low_cnt += 1;
    429 		}
    430 		low_cnt = 0;
    431 		sleep(1);
    432 	}
    433 	PTHREAD_REQUIRE(mutex_lock(&mutex, &ts_lengthy));
    434 	if (start == 0)
    435 		start = 1;
    436 	PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
    437 
    438 	return 0;
    439 }
    440 
    441 ATF_TC(mutex6);
    442 ATF_TC_HEAD(mutex6, tc)
    443 {
    444 	atf_tc_set_md_var(tc, "descr",
    445 	    "Checks scheduling for priority ceiling");
    446 	atf_tc_set_md_var(tc, "require.user", "root");
    447 }
    448 
    449 /*
    450  * 1. main thread sets itself to be a realtime task and launched two tasks,
    451  *    one has higher priority and the other has lower priority.
    452  * 2. each child thread(low and high priority thread) sets its scheduler and
    453  *    priority.
    454  * 3. each child thread did several rounds of computation, after each round it
    455  *    sleep 1 second.
    456  * 4. the child thread with low priority will call _sched_protect to increase
    457  *    its protect priority.
    458  * 5. We verify the thread with low priority runs first.
    459  *
    460  * Why does it work? From the main thread, we launched the high
    461  * priority thread first. This gives this thread the benefit of
    462  * starting first. The low priority thread did not call _sched_protect(2).
    463  * The high priority thread should finish the task first. After each
    464  * round of computation, we call sleep, to put the task into the
    465  * sleep queue, and wake up again after the timer expires. This
    466  * gives the scheduler the chance to decide which task to run. So,
    467  * the thread with real high priority will always block the thread
    468  * with real low priority.
    469  *
    470  */
    471 ATF_TC_BODY(mutex6, tc)
    472 {
    473 	struct sched_param param;
    474 	int res;
    475 	pthread_t high, low;
    476 
    477 	min_fifo_prio = sched_get_priority_min(SCHED_FIFO);
    478 	max_fifo_prio = sched_get_priority_max(SCHED_FIFO);
    479 	PTHREAD_REQUIRE(pthread_mutex_init(&mutex, NULL));
    480 	printf("min_fifo_prio = %d, max_fifo_info = %d\n", min_fifo_prio,
    481 	    max_fifo_prio);
    482 
    483 	param.sched_priority = min_fifo_prio;
    484 	res = sched_setscheduler(getpid(), SCHED_FIFO, &param);
    485 	printf("previous policy used = %d\n", res);
    486 
    487 	res = sched_getscheduler(getpid());
    488 	ATF_REQUIRE_EQ(res, 1);
    489 	PTHREAD_REQUIRE(pthread_create(&high, NULL, high_prio, NULL));
    490 	PTHREAD_REQUIRE(pthread_create(&low, NULL, low_prio, NULL));
    491 	sleep(5);
    492 	PTHREAD_REQUIRE(pthread_join(low, NULL));
    493 	PTHREAD_REQUIRE(pthread_join(high, NULL));
    494 
    495 	ATF_REQUIRE_EQ_MSG(start, 1, "start = %d, low_cnt =%ju, "
    496 	    "high_cnt = %ju\n", start, high_cnt, low_cnt);
    497 }
    498 
    499 ATF_TC(mutexattr1);
    500 ATF_TC_HEAD(mutexattr1, tc)
    501 {
    502 	atf_tc_set_md_var(tc, "descr", "Checks mutexattr");
    503 }
    504 
    505 ATF_TC_BODY(mutexattr1, tc)
    506 {
    507 	pthread_mutexattr_t mattr;
    508 	int protocol, target;
    509 
    510 	PTHREAD_REQUIRE(pthread_mutexattr_init(&mattr));
    511 
    512 	target = PTHREAD_PRIO_NONE;
    513 	PTHREAD_REQUIRE(pthread_mutexattr_setprotocol(&mattr, target));
    514 	PTHREAD_REQUIRE(pthread_mutexattr_getprotocol(&mattr, &protocol));
    515 	ATF_REQUIRE_EQ(protocol, target);
    516 
    517 	/*
    518 	target = PTHREAD_PRIO_INHERIT;
    519 	PTHREAD_REQUIRE(pthread_mutexattr_setprotocol(&mattr, target));
    520 	PTHREAD_REQUIRE(pthread_mutexattr_getprotocol(&mattr, &protocol));
    521 	ATF_REQUIRE_EQ(protocol, target);
    522 	*/
    523 
    524 	target = PTHREAD_PRIO_PROTECT;
    525 	PTHREAD_REQUIRE(pthread_mutexattr_setprotocol(&mattr, target));
    526 	PTHREAD_REQUIRE(pthread_mutexattr_getprotocol(&mattr, &protocol));
    527 	ATF_REQUIRE_EQ(protocol, target);
    528 }
    529 
    530 ATF_TC(mutexattr2);
    531 ATF_TC_HEAD(mutexattr2, tc)
    532 {
    533 	atf_tc_set_md_var(tc, "descr", "Checks mutexattr");
    534 }
    535 
    536 ATF_TC_BODY(mutexattr2, tc)
    537 {
    538 	pthread_mutexattr_t mattr;
    539 
    540 	PTHREAD_REQUIRE(pthread_mutexattr_init(&mattr));
    541 	int max_prio = sched_get_priority_max(SCHED_FIFO);
    542 	int min_prio = sched_get_priority_min(SCHED_FIFO);
    543 	for (int i = min_prio; i <= max_prio; i++) {
    544 		int prioceiling;
    545 		int protocol;
    546 
    547 		PTHREAD_REQUIRE(pthread_mutexattr_getprotocol(&mattr,
    548 		    &protocol));
    549 
    550 		printf("priority: %d\nprotocol: %d\n", i, protocol);
    551 		PTHREAD_REQUIRE(pthread_mutexattr_setprioceiling(&mattr, i));
    552 		PTHREAD_REQUIRE(pthread_mutexattr_getprioceiling(&mattr,
    553 		    &prioceiling));
    554 		printf("prioceiling: %d\n", prioceiling);
    555 		ATF_REQUIRE_EQ(i, prioceiling);
    556 	}
    557 }
    558 
    559 #ifdef TIMEDMUTEX
    560 ATF_TC(timedmutex1);
    561 ATF_TC_HEAD(timedmutex1, tc)
    562 {
    563 	atf_tc_set_md_var(tc, "descr", "Checks timeout on selflock");
    564 }
    565 
    566 ATF_TC_BODY(timedmutex1, tc)
    567 {
    568 
    569 	printf("Timed mutex-test 1\n");
    570 
    571 	PTHREAD_REQUIRE(pthread_mutex_init(&mutex, NULL));
    572 
    573 	printf("Before acquiring mutex\n");
    574 	PTHREAD_REQUIRE(pthread_mutex_lock(&mutex));
    575 
    576 	printf("Before endeavor to reacquire timed-mutex (timeout expected)\n");
    577 	PTHREAD_REQUIRE_STATUS(mutex_lock(&mutex, &ts_shortlived),
    578 	    ETIMEDOUT);
    579 
    580 	printf("Unlocking mutex\n");
    581 	PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
    582 }
    583 
    584 ATF_TC(timedmutex2);
    585 ATF_TC_HEAD(timedmutex2, tc)
    586 {
    587 	atf_tc_set_md_var(tc, "descr",
    588 	    "Checks timeout on selflock with timedlock");
    589 }
    590 
    591 ATF_TC_BODY(timedmutex2, tc)
    592 {
    593 
    594 	printf("Timed mutex-test 2\n");
    595 
    596 	PTHREAD_REQUIRE(pthread_mutex_init(&mutex, NULL));
    597 
    598 	printf("Before acquiring mutex with timedlock\n");
    599 	PTHREAD_REQUIRE(mutex_lock(&mutex, &ts_lengthy));
    600 
    601 	printf("Before endeavor to reacquire timed-mutex (timeout expected)\n");
    602 	PTHREAD_REQUIRE_STATUS(mutex_lock(&mutex, &ts_shortlived),
    603 	    ETIMEDOUT);
    604 
    605 	printf("Unlocking mutex\n");
    606 	PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
    607 }
    608 
    609 ATF_TC(timedmutex3);
    610 ATF_TC_HEAD(timedmutex3, tc)
    611 {
    612 	atf_tc_set_md_var(tc, "descr",
    613 	    "Checks timeout on selflock in a new thread");
    614 }
    615 
    616 static void *
    617 timedmtx_thrdfunc(void *arg)
    618 {
    619 	printf("Before endeavor to reacquire timed-mutex (timeout expected)\n");
    620 	PTHREAD_REQUIRE_STATUS(mutex_lock(&mutex, &ts_shortlived),
    621 	    ETIMEDOUT);
    622 
    623 	return NULL;
    624 }
    625 
    626 ATF_TC_BODY(timedmutex3, tc)
    627 {
    628 	pthread_t new;
    629 
    630 	printf("Timed mutex-test 3\n");
    631 
    632 	PTHREAD_REQUIRE(pthread_mutex_init(&mutex, NULL));
    633 
    634 	printf("Before acquiring mutex with timedlock\n");
    635 	PTHREAD_REQUIRE(pthread_mutex_lock(&mutex));
    636 
    637 	printf("Before creating new thread\n");
    638 	PTHREAD_REQUIRE(pthread_create(&new, NULL, timedmtx_thrdfunc, NULL));
    639 
    640 	printf("Before joining the mutex\n");
    641 	PTHREAD_REQUIRE(pthread_join(new, NULL));
    642 
    643 	printf("Unlocking mutex\n");
    644 	PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
    645 }
    646 
    647 ATF_TC(timedmutex4);
    648 ATF_TC_HEAD(timedmutex4, tc)
    649 {
    650 	atf_tc_set_md_var(tc, "descr",
    651 	    "Checks timeout on selflock with timedlock in a new thread");
    652 }
    653 
    654 ATF_TC_BODY(timedmutex4, tc)
    655 {
    656 	pthread_t new;
    657 
    658 	printf("Timed mutex-test 4\n");
    659 
    660 	PTHREAD_REQUIRE(pthread_mutex_init(&mutex, NULL));
    661 
    662 	printf("Before acquiring mutex with timedlock\n");
    663 	PTHREAD_REQUIRE(mutex_lock(&mutex, &ts_lengthy));
    664 
    665 	printf("Before creating new thread\n");
    666 	PTHREAD_REQUIRE(pthread_create(&new, NULL, timedmtx_thrdfunc, NULL));
    667 
    668 	printf("Before joining the mutex\n");
    669 	PTHREAD_REQUIRE(pthread_join(new, NULL));
    670 
    671 	printf("Unlocking mutex\n");
    672 	PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
    673 }
    674 #endif
    675 
    676 ATF_TP_ADD_TCS(tp)
    677 {
    678 	ATF_TP_ADD_TC(tp, mutex1);
    679 	ATF_TP_ADD_TC(tp, mutex2);
    680 	ATF_TP_ADD_TC(tp, mutex3);
    681 	ATF_TP_ADD_TC(tp, mutex4);
    682 	ATF_TP_ADD_TC(tp, mutex5);
    683 	ATF_TP_ADD_TC(tp, mutex6);
    684 	ATF_TP_ADD_TC(tp, mutexattr1);
    685 	ATF_TP_ADD_TC(tp, mutexattr2);
    686 
    687 #ifdef TIMEDMUTEX
    688 	ATF_TP_ADD_TC(tp, timedmutex1);
    689 	ATF_TP_ADD_TC(tp, timedmutex2);
    690 	ATF_TP_ADD_TC(tp, timedmutex3);
    691 	ATF_TP_ADD_TC(tp, timedmutex4);
    692 #endif
    693 
    694 	return atf_no_error();
    695 }
    696