| commit 5aded6f2abbe19bc77e563b7db10aa9dd037a90d |
| Author: Andreas Schwab <schwab@suse.de> |
| Date: Wed Jan 13 16:04:42 2016 +0100 |
| |
| Don't do lock elision on an error checking mutex (bug 17514) |
| |
| Error checking mutexes are not supposed to be subject to lock elision. |
| That would defeat the error checking nature of the mutex because lock |
| elision doesn't record ownership. |
| |
| |
| |
| |
| @@ -266,7 +266,8 @@ tests = tst-typesizes \ |
| tst-abstime \ |
| tst-vfork1 tst-vfork2 tst-vfork1x tst-vfork2x \ |
| tst-getpid1 tst-getpid2 tst-getpid3 \ |
| - tst-initializers1 $(patsubst %,tst-initializers1-%,c89 gnu89 c99 gnu99) |
| + tst-initializers1 $(patsubst %,tst-initializers1-%,c89 gnu89 c99 gnu99) \ |
| + tst-mutex-errorcheck |
| xtests = tst-setuid1 tst-setuid1-static tst-mutexpp1 tst-mutexpp6 tst-mutexpp10 |
| test-srcs = tst-oddstacklimit |
| |
| |
| |
| |
| |
| @@ -87,7 +87,8 @@ pthread_mutex_timedlock (mutex, abstime) |
| if (__builtin_expect (mutex->__data.__owner == id, 0)) |
| return EDEADLK; |
| |
| - /* FALLTHROUGH */ |
| + /* Don't do lock elision on an error checking mutex. */ |
| + goto simple; |
| |
| case PTHREAD_MUTEX_TIMED_NP: |
| FORCE_ELISION (mutex, goto elision); |
| |
| |
| |
| |
| @@ -0,0 +1,61 @@ |
| +/* Check that error checking mutexes are not subject to lock elision. |
| + Copyright (C) 2016 Free Software Foundation, Inc. |
| + This file is part of the GNU C Library. |
| + |
| + The GNU C Library is free software; you can redistribute it and/or |
| + modify it under the terms of the GNU Lesser General Public |
| + License as published by the Free Software Foundation; either |
| + version 2.1 of the License, or (at your option) any later version. |
| + |
| + The GNU C Library is distributed in the hope that it will be useful, |
| + but WITHOUT ANY WARRANTY; without even the implied warranty of |
| + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| + Lesser General Public License for more details. |
| + |
| + You should have received a copy of the GNU Lesser General Public |
| + License along with the GNU C Library; if not, see |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#include <stdio.h> |
| +#include <errno.h> |
| +#include <time.h> |
| +#include <pthread.h> |
| + |
| +static int |
| +do_test (void) |
| +{ |
| + struct timespec tms = { 0 }; |
| + pthread_mutex_t mutex; |
| + pthread_mutexattr_t mutexattr; |
| + int ret = 0; |
| + |
| + if (pthread_mutexattr_init (&mutexattr) != 0) |
| + return 1; |
| + if (pthread_mutexattr_settype (&mutexattr, PTHREAD_MUTEX_ERRORCHECK) != 0) |
| + return 1; |
| + |
| + if (pthread_mutex_init (&mutex, &mutexattr) != 0) |
| + return 1; |
| + if (pthread_mutexattr_destroy (&mutexattr) != 0) |
| + return 1; |
| + |
| + /* The call to pthread_mutex_timedlock erroneously enabled lock elision |
| + on the mutex, which then triggered an assertion failure in |
| + pthread_mutex_unlock. It would also defeat the error checking nature |
| + of the mutex. */ |
| + if (pthread_mutex_timedlock (&mutex, &tms) != 0) |
| + return 1; |
| + if (pthread_mutex_timedlock (&mutex, &tms) != EDEADLK) |
| + { |
| + printf ("Failed error checking on locked mutex\n"); |
| + ret = 1; |
| + } |
| + |
| + if (pthread_mutex_unlock (&mutex) != 0) |
| + ret = 1; |
| + |
| + return ret; |
| +} |
| + |
| +#define TEST_FUNCTION do_test () |
| +#include "../test-skeleton.c" |