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