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