diff options
author | Carlos O'Donell <carlos@redhat.com> | 2017-07-29 00:02:03 -0400 |
---|---|---|
committer | Carlos O'Donell <carlos@redhat.com> | 2017-07-29 00:02:03 -0400 |
commit | 5920a4a624b1f4db310d1c44997b640e2a4653e5 (patch) | |
tree | e58989b49f6aae484bcdf13adad65bdbe79273e3 /nptl/tst-mutex7.c | |
parent | d95fcb2df478efbf4f8537ba898374043ac4561f (diff) | |
download | glibc-5920a4a624b1f4db310d1c44997b640e2a4653e5.tar.gz glibc-5920a4a624b1f4db310d1c44997b640e2a4653e5.tar.xz glibc-5920a4a624b1f4db310d1c44997b640e2a4653e5.zip |
mutex: Fix robust mutex lock acquire (Bug 21778)
65810f0ef05e8c9e333f17a44e77808b163ca298 fixed a robust mutex bug but introduced BZ 21778: if the CAS used to try to acquire a lock fails, the expected value is not updated, which breaks other cases in the loce acquisition loop. The fix is to simply update the expected value with the value returned by the CAS, which ensures that behavior is as if the first case with the CAS never happened (if the CAS fails). This is a regression introduced in the last release. Tested on x86_64, i686, ppc64, ppc64le, s390x, aarch64, armv7hl.
Diffstat (limited to 'nptl/tst-mutex7.c')
-rw-r--r-- | nptl/tst-mutex7.c | 45 |
1 files changed, 35 insertions, 10 deletions
diff --git a/nptl/tst-mutex7.c b/nptl/tst-mutex7.c index a11afdba5e..08fe251eeb 100644 --- a/nptl/tst-mutex7.c +++ b/nptl/tst-mutex7.c @@ -22,25 +22,41 @@ #include <stdlib.h> #include <time.h> - +/* This test is a template for other tests to use. Other tests define + the following macros to change the behaviour of the template test. + The test is very simple, it configures N threads given the parameters + below and then proceeds to go through mutex lock and unlock + operations in each thread as described before for the thread + function. */ #ifndef TYPE # define TYPE PTHREAD_MUTEX_DEFAULT #endif - +#ifndef ROBUST +# define ROBUST PTHREAD_MUTEX_STALLED +#endif +#ifndef DELAY_NSEC +# define DELAY_NSEC 11000 +#endif +#ifndef ROUNDS +# define ROUNDS 1000 +#endif +#ifndef N +# define N 100 +#endif static pthread_mutex_t lock; - -#define ROUNDS 1000 -#define N 100 - - +/* Each thread locks and the subsequently unlocks the lock, yielding + the smallest critical section possible. After the unlock the thread + waits DELAY_NSEC nanoseconds before doing the lock and unlock again. + Every thread does this ROUNDS times. The lock and unlock are + checked for errors. */ static void * tf (void *arg) { int nr = (long int) arg; int cnt; - struct timespec ts = { .tv_sec = 0, .tv_nsec = 11000 }; + struct timespec ts = { .tv_sec = 0, .tv_nsec = DELAY_NSEC }; for (cnt = 0; cnt < ROUNDS; ++cnt) { @@ -56,13 +72,16 @@ tf (void *arg) return (void *) 1l; } - nanosleep (&ts, NULL); + if ((ts.tv_sec > 0) || (ts.tv_nsec > 0)) + nanosleep (&ts, NULL); } return NULL; } - +/* Setup and run N threads, where each thread does as described + in the above thread function. The threads are given a minimal 1MiB + stack since they don't do anything between the lock and unlock. */ static int do_test (void) { @@ -80,6 +99,12 @@ do_test (void) exit (1); } + if (pthread_mutexattr_setrobust (&a, ROBUST) != 0) + { + puts ("mutexattr_setrobust failed"); + exit (1); + } + #ifdef ENABLE_PI if (pthread_mutexattr_setprotocol (&a, PTHREAD_PRIO_INHERIT) != 0) { |