From patchwork Thu Jan 14 09:40:47 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andreas Schwab X-Patchwork-Id: 10374 Received: (qmail 80494 invoked by alias); 14 Jan 2016 09:40:53 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 80477 invoked by uid 89); 14 Jan 2016 09:40:52 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_LOW, RP_MATCHES_RCVD, SPF_PASS autolearn=ham version=3.3.2 spammy=fallthrough, pthread_mutex_t, tms, defeat X-HELO: mx2.suse.de From: Andreas Schwab To: libc-alpha@sourceware.org Subject: [PATCH] Don't do lock elision on an error checking mutex (bug 17514) X-Yow: I'm into SOFTWARE! Date: Thu, 14 Jan 2016 10:40:47 +0100 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.5 (gnu/linux) MIME-Version: 1.0 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. [BZ #17514] * nptl/pthread_mutex_timedlock.c (pthread_mutex_timedlock) : Don't do lock elision. * nptl/Makefile (tests): Add tst-mutex-errorcheck. * nptl/tst-mutex-errorcheck.c: New file. --- nptl/Makefile | 2 +- nptl/pthread_mutex_timedlock.c | 3 ++- nptl/tst-mutex-errorcheck.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 nptl/tst-mutex-errorcheck.c diff --git a/nptl/Makefile b/nptl/Makefile index 66364d7..9dda4df 100644 --- a/nptl/Makefile +++ b/nptl/Makefile @@ -288,7 +288,7 @@ tests = tst-typesizes \ tst-initializers1 $(addprefix tst-initializers1-,\ c89 gnu89 c99 gnu99 c11 gnu11) \ tst-bad-schedattr \ - tst-thread_local1 + tst-thread_local1 tst-mutex-errorcheck xtests = tst-setuid1 tst-setuid1-static tst-setuid2 \ tst-mutexpp1 tst-mutexpp6 tst-mutexpp10 test-srcs = tst-oddstacklimit diff --git a/nptl/pthread_mutex_timedlock.c b/nptl/pthread_mutex_timedlock.c index 9055e11..07f0901 100644 --- a/nptl/pthread_mutex_timedlock.c +++ b/nptl/pthread_mutex_timedlock.c @@ -89,7 +89,8 @@ pthread_mutex_timedlock (pthread_mutex_t *mutex, if (__glibc_unlikely (mutex->__data.__owner == id)) 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); diff --git a/nptl/tst-mutex-errorcheck.c b/nptl/tst-mutex-errorcheck.c new file mode 100644 index 0000000..58d0ff9 --- /dev/null +++ b/nptl/tst-mutex-errorcheck.c @@ -0,0 +1,42 @@ +/* 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 + . */ + +#include +#include + +int +main (void) +{ + struct timespec tms = { 0 }; + pthread_mutex_t mutex; + pthread_mutexattr_t mutexattr; + + pthread_mutexattr_init (&mutexattr); + pthread_mutexattr_settype (&mutexattr, PTHREAD_MUTEX_ERRORCHECK_NP); + + pthread_mutex_init (&mutex, &mutexattr); + pthread_mutexattr_destroy (&mutexattr); + + pthread_mutex_timedlock (&mutex, &tms); + /* The preceding call to pthread_mutex_timedlock erroneously enabled + lock elision on the mutex, which triggered an assertion failure + during unlock. */ + pthread_mutex_unlock (&mutex); + + return 0; +}