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