diff options
| author | Enji Cooper <ngie@FreeBSD.org> | 2017-01-12 07:26:39 +0000 |
|---|---|---|
| committer | Enji Cooper <ngie@FreeBSD.org> | 2017-01-12 07:26:39 +0000 |
| commit | 20d24fbb933deae4ccdc875f54babfff8dace678 (patch) | |
| tree | 086ca5a4b87d5f393d00711903b00279a7ec14e3 /lib/libpthread | |
| parent | 2254eda87e053e92fb9e0bd34a1fb5db0d9d7cd7 (diff) | |
Notes
Diffstat (limited to 'lib/libpthread')
| -rw-r--r-- | lib/libpthread/Makefile | 3 | ||||
| -rw-r--r-- | lib/libpthread/h_common.h | 6 | ||||
| -rw-r--r-- | lib/libpthread/t_mutex.c | 194 |
3 files changed, 180 insertions, 23 deletions
diff --git a/lib/libpthread/Makefile b/lib/libpthread/Makefile index 4f227aaa8eff..cb84bcd0a807 100644 --- a/lib/libpthread/Makefile +++ b/lib/libpthread/Makefile @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.11 2013/04/12 17:18:11 christos Exp $ +# $NetBSD: Makefile,v 1.12 2016/10/30 16:17:16 kamil Exp $ NOMAN= # defined @@ -38,6 +38,7 @@ TESTS_C+= t_sigsuspend TESTS_C+= t_siglongjmp TESTS_C+= t_sleep TESTS_C+= t_swapcontext +TESTS_C+= t_timedmutex LDADD.t_sem+= -lrt diff --git a/lib/libpthread/h_common.h b/lib/libpthread/h_common.h index f4d03bcdec9e..2e8b0a123e75 100644 --- a/lib/libpthread/h_common.h +++ b/lib/libpthread/h_common.h @@ -9,4 +9,10 @@ ATF_REQUIRE_MSG(ret == 0, "%s: %s", #x, strerror(ret)); \ } while (0) +#define PTHREAD_REQUIRE_STATUS(x, v) \ + do { \ + int ret = (x); \ + ATF_REQUIRE_MSG(ret == (v), "%s: %s", #x, strerror(ret)); \ + } while (0) + #endif // H_COMMON_H diff --git a/lib/libpthread/t_mutex.c b/lib/libpthread/t_mutex.c index f2cba5e4deec..e9ba2fc5754a 100644 --- a/lib/libpthread/t_mutex.c +++ b/lib/libpthread/t_mutex.c @@ -1,4 +1,4 @@ -/* $NetBSD: t_mutex.c,v 1.10 2016/07/31 13:01:29 christos Exp $ */ +/* $NetBSD: t_mutex.c,v 1.14 2016/10/31 23:51:20 christos Exp $ */ /* * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -29,12 +29,13 @@ #include <sys/cdefs.h> __COPYRIGHT("@(#) Copyright (c) 2008\ The NetBSD Foundation, inc. All rights reserved."); -__RCSID("$NetBSD: t_mutex.c,v 1.10 2016/07/31 13:01:29 christos Exp $"); +__RCSID("$NetBSD: t_mutex.c,v 1.14 2016/10/31 23:51:20 christos Exp $"); #include <pthread.h> #include <stdio.h> #include <string.h> #include <errno.h> +#include <time.h> #include <unistd.h> #include <sys/sched.h> #include <sys/param.h> @@ -47,6 +48,31 @@ static pthread_mutex_t mutex; static pthread_mutex_t static_mutex = PTHREAD_MUTEX_INITIALIZER; static int global_x; +#ifdef TIMEDMUTEX +/* This code is used for verifying non-timed specific code */ +static struct timespec ts_lengthy = { + .tv_sec = UINT16_MAX, + .tv_nsec = 0 +}; +/* This code is used for verifying timed-only specific code */ +static struct timespec ts_shortlived = { + .tv_sec = 0, + .tv_nsec = 120 +}; + +static int +mutex_lock(pthread_mutex_t *m, const struct timespec *ts) +{ + struct timespec ts_wait; + ATF_REQUIRE(clock_gettime(CLOCK_REALTIME, &ts_wait) != -1); + timespecadd(&ts_wait, ts, &ts_wait); + + return pthread_mutex_timedlock(m, &ts_wait); +} +#else +#define mutex_lock(a, b) pthread_mutex_lock(a) +#endif + static void * mutex1_threadfunc(void *arg) { @@ -56,7 +82,7 @@ mutex1_threadfunc(void *arg) param = arg; printf("2: Locking mutex\n"); - pthread_mutex_lock(&mutex); + mutex_lock(&mutex, &ts_lengthy); printf("2: Got mutex. *param = %d\n", *param); ATF_REQUIRE_EQ(*param, 20); (*param)++; @@ -81,7 +107,7 @@ ATF_TC_BODY(mutex1, tc) PTHREAD_REQUIRE(pthread_mutex_init(&mutex, NULL)); x = 1; - PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); + PTHREAD_REQUIRE(mutex_lock(&mutex, &ts_lengthy)); PTHREAD_REQUIRE(pthread_create(&new, NULL, mutex1_threadfunc, &x)); printf("1: Before changing the value.\n"); sleep(2); @@ -92,7 +118,7 @@ ATF_TC_BODY(mutex1, tc) printf("1: After releasing the mutex.\n"); PTHREAD_REQUIRE(pthread_join(new, &joinval)); - PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); + PTHREAD_REQUIRE(mutex_lock(&mutex, &ts_lengthy)); printf("1: Thread joined. X was %d. Return value (int) was %d\n", x, *(int *)joinval); ATF_REQUIRE_EQ(x, 21); @@ -108,7 +134,7 @@ mutex2_threadfunc(void *arg) printf("2: Second thread (%p). Count is %ld\n", pthread_self(), count); while (count--) { - PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); + PTHREAD_REQUIRE(mutex_lock(&mutex, &ts_lengthy)); global_x++; PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); } @@ -141,7 +167,7 @@ ATF_TC_BODY(mutex2, tc) global_x = 0; count = count2 = 10000000; - PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); + PTHREAD_REQUIRE(mutex_lock(&mutex, &ts_lengthy)); PTHREAD_REQUIRE(pthread_create(&new, NULL, mutex2_threadfunc, &count2)); printf("1: Thread %p\n", pthread_self()); @@ -149,14 +175,14 @@ ATF_TC_BODY(mutex2, tc) PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); while (count--) { - PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); + PTHREAD_REQUIRE(mutex_lock(&mutex, &ts_lengthy)); global_x++; PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); } PTHREAD_REQUIRE(pthread_join(new, &joinval)); - PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); + PTHREAD_REQUIRE(mutex_lock(&mutex, &ts_lengthy)); printf("1: Thread joined. X was %d. Return value (long) was %ld\n", global_x, (long)joinval); ATF_REQUIRE_EQ(global_x, 20000000); @@ -178,7 +204,7 @@ mutex3_threadfunc(void *arg) printf("2: Second thread (%p). Count is %ld\n", pthread_self(), count); while (count--) { - PTHREAD_REQUIRE(pthread_mutex_lock(&static_mutex)); + PTHREAD_REQUIRE(mutex_lock(&static_mutex, &ts_lengthy)); global_x++; PTHREAD_REQUIRE(pthread_mutex_unlock(&static_mutex)); } @@ -210,7 +236,7 @@ ATF_TC_BODY(mutex3, tc) global_x = 0; count = count2 = 10000000; - PTHREAD_REQUIRE(pthread_mutex_lock(&static_mutex)); + PTHREAD_REQUIRE(mutex_lock(&static_mutex, &ts_lengthy)); PTHREAD_REQUIRE(pthread_create(&new, NULL, mutex3_threadfunc, &count2)); printf("1: Thread %p\n", pthread_self()); @@ -218,14 +244,14 @@ ATF_TC_BODY(mutex3, tc) PTHREAD_REQUIRE(pthread_mutex_unlock(&static_mutex)); while (count--) { - PTHREAD_REQUIRE(pthread_mutex_lock(&static_mutex)); + PTHREAD_REQUIRE(mutex_lock(&static_mutex, &ts_lengthy)); global_x++; PTHREAD_REQUIRE(pthread_mutex_unlock(&static_mutex)); } PTHREAD_REQUIRE(pthread_join(new, &joinval)); - PTHREAD_REQUIRE(pthread_mutex_lock(&static_mutex)); + PTHREAD_REQUIRE(mutex_lock(&static_mutex, &ts_lengthy)); printf("1: Thread joined. X was %d. Return value (long) was %ld\n", global_x, (long)joinval); ATF_REQUIRE_EQ(global_x, 20000000); @@ -248,7 +274,7 @@ mutex4_threadfunc(void *arg) param = arg; printf("2: Locking mutex\n"); - PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); + PTHREAD_REQUIRE(mutex_lock(&mutex, &ts_lengthy)); printf("2: Got mutex. *param = %d\n", *param); (*param)++; @@ -279,11 +305,11 @@ ATF_TC_BODY(mutex4, tc) PTHREAD_REQUIRE(pthread_mutexattr_destroy(&mattr)); x = 1; - PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); + PTHREAD_REQUIRE(mutex_lock(&mutex, &ts_lengthy)); PTHREAD_REQUIRE(pthread_create(&new, NULL, mutex4_threadfunc, &x)); printf("1: Before recursively acquiring the mutex.\n"); - PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); + PTHREAD_REQUIRE(mutex_lock(&mutex, &ts_lengthy)); printf("1: Before releasing the mutex once.\n"); sleep(2); @@ -299,7 +325,7 @@ ATF_TC_BODY(mutex4, tc) PTHREAD_REQUIRE(pthread_join(new, &joinval)); - PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); + PTHREAD_REQUIRE(mutex_lock(&mutex, &ts_lengthy)); printf("1: Thread joined. X was %d. Return value (int) was %d\n", x, *(int *)joinval); ATF_REQUIRE_EQ(x, 21); @@ -320,7 +346,7 @@ child_func(void* arg) res = _sched_protect(-2); ATF_REQUIRE_EQ_MSG(res, -1, "sched_protect returned %d", res); ATF_REQUIRE_EQ(errno, ENOENT); - PTHREAD_REQUIRE(pthread_mutex_lock(&mutex5)); + PTHREAD_REQUIRE(mutex_lock(&mutex5, &ts_lengthy)); printf("child is owning resource\n"); res = _sched_protect(-2); ATF_REQUIRE_EQ(res, max_fifo_prio); @@ -363,7 +389,7 @@ ATF_TC_BODY(mutex5, tc) max_fifo_prio)); PTHREAD_REQUIRE(pthread_mutex_init(&mutex5, &attr5)); - PTHREAD_REQUIRE(pthread_mutex_lock(&mutex5)); + PTHREAD_REQUIRE(mutex_lock(&mutex5, &ts_lengthy)); printf("enter critical section for main\n"); PTHREAD_REQUIRE(pthread_create(&child, NULL, child_func, NULL)); printf("main starts to sleep\n"); @@ -401,7 +427,7 @@ high_prio(void* arg) high_cnt = 0; sleep(1); } - PTHREAD_REQUIRE(pthread_mutex_lock(&mutex6)); + PTHREAD_REQUIRE(mutex_lock(&mutex6, &ts_lengthy)); if (start == 0) start = 2; PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex6)); @@ -433,7 +459,7 @@ low_prio(void* arg) low_cnt = 0; sleep(1); } - PTHREAD_REQUIRE(pthread_mutex_lock(&mutex6)); + PTHREAD_REQUIRE(mutex_lock(&mutex6, &ts_lengthy)); if (start == 0) start = 1; PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex6)); @@ -551,6 +577,123 @@ ATF_TC_BODY(mutexattr2, tc) } } +#ifdef TIMEDMUTEX +ATF_TC(timedmutex1); +ATF_TC_HEAD(timedmutex1, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks timeout on selflock"); +} + +ATF_TC_BODY(timedmutex1, tc) +{ + + printf("Timed mutex-test 1\n"); + + PTHREAD_REQUIRE(pthread_mutex_init(&mutex, NULL)); + + printf("Before acquiring mutex\n"); + PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); + + printf("Before endeavor to reacquire timed-mutex (timeout expected)\n"); + PTHREAD_REQUIRE_STATUS(mutex_lock(&mutex, &ts_shortlived), + ETIMEDOUT); + + printf("Unlocking mutex\n"); + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); +} + +ATF_TC(timedmutex2); +ATF_TC_HEAD(timedmutex2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks timeout on selflock with timedlock"); +} + +ATF_TC_BODY(timedmutex2, tc) +{ + + printf("Timed mutex-test 2\n"); + + PTHREAD_REQUIRE(pthread_mutex_init(&mutex, NULL)); + + printf("Before acquiring mutex with timedlock\n"); + PTHREAD_REQUIRE(mutex_lock(&mutex, &ts_lengthy)); + + printf("Before endeavor to reacquire timed-mutex (timeout expected)\n"); + PTHREAD_REQUIRE_STATUS(mutex_lock(&mutex, &ts_shortlived), + ETIMEDOUT); + + printf("Unlocking mutex\n"); + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); +} + +ATF_TC(timedmutex3); +ATF_TC_HEAD(timedmutex3, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks timeout on selflock in a new thread"); +} + +static void * +timedmtx_thrdfunc(void *arg) +{ + printf("Before endeavor to reacquire timed-mutex (timeout expected)\n"); + PTHREAD_REQUIRE_STATUS(mutex_lock(&mutex, &ts_shortlived), + ETIMEDOUT); + + return NULL; +} + +ATF_TC_BODY(timedmutex3, tc) +{ + pthread_t new; + + printf("Timed mutex-test 3\n"); + + PTHREAD_REQUIRE(pthread_mutex_init(&mutex, NULL)); + + printf("Before acquiring mutex with timedlock\n"); + PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); + + printf("Before creating new thread\n"); + PTHREAD_REQUIRE(pthread_create(&new, NULL, timedmtx_thrdfunc, NULL)); + + printf("Before joining the mutex\n"); + PTHREAD_REQUIRE(pthread_join(new, NULL)); + + printf("Unlocking mutex\n"); + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); +} + +ATF_TC(timedmutex4); +ATF_TC_HEAD(timedmutex4, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks timeout on selflock with timedlock in a new thread"); +} + +ATF_TC_BODY(timedmutex4, tc) +{ + pthread_t new; + + printf("Timed mutex-test 4\n"); + + PTHREAD_REQUIRE(pthread_mutex_init(&mutex, NULL)); + + printf("Before acquiring mutex with timedlock\n"); + PTHREAD_REQUIRE(mutex_lock(&mutex, &ts_lengthy)); + + printf("Before creating new thread\n"); + PTHREAD_REQUIRE(pthread_create(&new, NULL, timedmtx_thrdfunc, NULL)); + + printf("Before joining the mutex\n"); + PTHREAD_REQUIRE(pthread_join(new, NULL)); + + printf("Unlocking mutex\n"); + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); +} +#endif + ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, mutex1); @@ -561,6 +704,13 @@ ATF_TP_ADD_TCS(tp) ATF_TP_ADD_TC(tp, mutex6); ATF_TP_ADD_TC(tp, mutexattr1); ATF_TP_ADD_TC(tp, mutexattr2); - + +#ifdef TIMEDMUTEX + ATF_TP_ADD_TC(tp, timedmutex1); + ATF_TP_ADD_TC(tp, timedmutex2); + ATF_TP_ADD_TC(tp, timedmutex3); + ATF_TP_ADD_TC(tp, timedmutex4); +#endif + return atf_no_error(); } |
