diff options
Diffstat (limited to 'nptl/tst-rwlock9.c')
-rw-r--r-- | nptl/tst-rwlock9.c | 186 |
1 files changed, 88 insertions, 98 deletions
diff --git a/nptl/tst-rwlock9.c b/nptl/tst-rwlock9.c index 3c851fa927..3229a6fb42 100644 --- a/nptl/tst-rwlock9.c +++ b/nptl/tst-rwlock9.c @@ -1,5 +1,5 @@ /* Test program for timedout read/write lock functions. - Copyright (C) 2000-2018 Free Software Foundation, Inc. + Copyright (C) 2000-2019 Free Software Foundation, Inc. Contributed by Ulrich Drepper <drepper@redhat.com>, 2000. The GNU C Library is free software; you can redistribute it and/or @@ -14,7 +14,7 @@ You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; see the file COPYING.LIB. If - not, see <http://www.gnu.org/licenses/>. */ + not, see <https://www.gnu.org/licenses/>. */ #include <errno.h> #include <error.h> @@ -24,6 +24,9 @@ #include <time.h> #include <unistd.h> #include <sys/time.h> +#include <support/check.h> +#include <support/timespec.h> +#include <support/xthread.h> #define NWRITERS 15 @@ -31,64 +34,68 @@ #define NREADERS 15 #define READTRIES 15 -#define TIMEOUT 1000000 -#define DELAY 1000000 +static const struct timespec timeout = { 0,1000000 }; +static const struct timespec delay = { 0, 1000000 }; #ifndef KIND # define KIND PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP #endif +/* A bogus clock value that tells the tests to use pthread_rwlock_timedrdlock + and pthread_rwlock_timedwrlock rather than pthread_rwlock_clockrdlock and + pthread_rwlock_clockwrlock. */ +#define CLOCK_USE_TIMEDLOCK (-1) + static pthread_rwlock_t lock; +struct thread_args +{ + int nr; + clockid_t clockid; + const char *fnname; +}; static void * -writer_thread (void *nr) +writer_thread (void *arg) { + struct thread_args *args = arg; + const int nr = args->nr; + const clockid_t clockid = args->clockid; + const clockid_t clockid_for_get = + (clockid == CLOCK_USE_TIMEDLOCK) ? CLOCK_REALTIME : clockid; + const char *fnname = args->fnname; + struct timespec ts; - struct timespec delay; int n; - delay.tv_sec = 0; - delay.tv_nsec = DELAY; - for (n = 0; n < WRITETRIES; ++n) { int e; do { - struct timeval tv; - (void) gettimeofday (&tv, NULL); - TIMEVAL_TO_TIMESPEC (&tv, &ts); + xclock_gettime (clockid_for_get, &ts); - ts.tv_nsec += 2 * TIMEOUT; - if (ts.tv_nsec >= 1000000000) - { - ts.tv_nsec -= 1000000000; - ++ts.tv_sec; - } + ts = timespec_add (ts, timeout); + ts = timespec_add (ts, timeout); - printf ("writer thread %ld tries again\n", (long int) nr); + printf ("writer thread %d tries again\n", nr); - e = pthread_rwlock_timedwrlock (&lock, &ts); + e = (clockid == CLOCK_USE_TIMEDLOCK) + ? pthread_rwlock_timedwrlock (&lock, &ts) + : pthread_rwlock_clockwrlock (&lock, clockid, &ts); if (e != 0 && e != ETIMEDOUT) - { - puts ("timedwrlock failed"); - exit (1); - } + FAIL_EXIT1 ("%swrlock failed", fnname); } while (e == ETIMEDOUT); - printf ("writer thread %ld succeeded\n", (long int) nr); + printf ("writer thread %d succeeded\n", nr); nanosleep (&delay, NULL); if (pthread_rwlock_unlock (&lock) != 0) - { - puts ("unlock for writer failed"); - exit (1); - } + FAIL_EXIT1 ("unlock for writer failed"); - printf ("writer thread %ld released\n", (long int) nr); + printf ("writer thread %d released\n", nr); } return NULL; @@ -96,53 +103,46 @@ writer_thread (void *nr) static void * -reader_thread (void *nr) +reader_thread (void *arg) { + struct thread_args *args = arg; + const int nr = args->nr; + const clockid_t clockid = args->clockid; + const clockid_t clockid_for_get = + (clockid == CLOCK_USE_TIMEDLOCK) ? CLOCK_REALTIME : clockid; + const char *fnname = args->fnname; + struct timespec ts; - struct timespec delay; int n; - delay.tv_sec = 0; - delay.tv_nsec = DELAY; - for (n = 0; n < READTRIES; ++n) { int e; do { - struct timeval tv; - (void) gettimeofday (&tv, NULL); - TIMEVAL_TO_TIMESPEC (&tv, &ts); + xclock_gettime (clockid_for_get, &ts); - ts.tv_nsec += TIMEOUT; - if (ts.tv_nsec >= 1000000000) - { - ts.tv_nsec -= 1000000000; - ++ts.tv_sec; - } + ts = timespec_add (ts, timeout); - printf ("reader thread %ld tries again\n", (long int) nr); + printf ("reader thread %d tries again\n", nr); - e = pthread_rwlock_timedrdlock (&lock, &ts); + if (clockid == CLOCK_USE_TIMEDLOCK) + e = pthread_rwlock_timedrdlock (&lock, &ts); + else + e = pthread_rwlock_clockrdlock (&lock, clockid, &ts); if (e != 0 && e != ETIMEDOUT) - { - puts ("timedrdlock failed"); - exit (1); - } + FAIL_EXIT1 ("%srdlock failed", fnname); } while (e == ETIMEDOUT); - printf ("reader thread %ld succeeded\n", (long int) nr); + printf ("reader thread %d succeeded\n", nr); nanosleep (&delay, NULL); if (pthread_rwlock_unlock (&lock) != 0) - { - puts ("unlock for reader failed"); - exit (1); - } + FAIL_EXIT1 ("unlock for reader failed"); - printf ("reader thread %ld released\n", (long int) nr); + printf ("reader thread %d released\n", nr); } return NULL; @@ -150,31 +150,21 @@ reader_thread (void *nr) static int -do_test (void) +do_test_clock (clockid_t clockid, const char *fnname) { pthread_t thwr[NWRITERS]; pthread_t thrd[NREADERS]; int n; - void *res; pthread_rwlockattr_t a; if (pthread_rwlockattr_init (&a) != 0) - { - puts ("rwlockattr_t failed"); - exit (1); - } + FAIL_EXIT1 ("rwlockattr_t failed"); if (pthread_rwlockattr_setkind_np (&a, KIND) != 0) - { - puts ("rwlockattr_setkind failed"); - exit (1); - } + FAIL_EXIT1 ("rwlockattr_setkind failed"); if (pthread_rwlock_init (&lock, &a) != 0) - { - puts ("rwlock_init failed"); - exit (1); - } + FAIL_EXIT1 ("rwlock_init failed"); /* Make standard error the same as standard output. */ dup2 (1, 2); @@ -182,40 +172,40 @@ do_test (void) /* Make sure we see all message, even those on stdout. */ setvbuf (stdout, NULL, _IONBF, 0); - for (n = 0; n < NWRITERS; ++n) - if (pthread_create (&thwr[n], NULL, writer_thread, - (void *) (long int) n) != 0) - { - puts ("writer create failed"); - exit (1); - } - - for (n = 0; n < NREADERS; ++n) - if (pthread_create (&thrd[n], NULL, reader_thread, - (void *) (long int) n) != 0) - { - puts ("reader create failed"); - exit (1); - } + struct thread_args wargs[NWRITERS]; + for (n = 0; n < NWRITERS; ++n) { + wargs[n].nr = n; + wargs[n].clockid = clockid; + wargs[n].fnname = fnname; + thwr[n] = xpthread_create (NULL, writer_thread, &wargs[n]); + } + + struct thread_args rargs[NREADERS]; + for (n = 0; n < NREADERS; ++n) { + rargs[n].nr = n; + rargs[n].clockid = clockid; + rargs[n].fnname = fnname; + thrd[n] = xpthread_create (NULL, reader_thread, &rargs[n]); + } /* Wait for all the threads. */ for (n = 0; n < NWRITERS; ++n) - if (pthread_join (thwr[n], &res) != 0) - { - puts ("writer join failed"); - exit (1); - } + xpthread_join (thwr[n]); for (n = 0; n < NREADERS; ++n) - if (pthread_join (thrd[n], &res) != 0) - { - puts ("reader join failed"); - exit (1); - } + xpthread_join (thrd[n]); + + return 0; +} + +static int +do_test (void) +{ + do_test_clock (CLOCK_USE_TIMEDLOCK, "timed"); + do_test_clock (CLOCK_REALTIME, "clock(realtime)"); + do_test_clock (CLOCK_MONOTONIC, "clock(monotonic)"); return 0; } -#undef TIMEOUT #define TIMEOUT 30 -#define TEST_FUNCTION do_test () -#include "../test-skeleton.c" +#include <support/test-driver.c> |