[Glibc-bsd-commits] r6080 - in trunk/glibc-ports-2.24: fbtl kfreebsd/fbtl

aurel32 at alioth.debian.org aurel32 at alioth.debian.org
Wed Jul 6 21:16:54 UTC 2016


Author: aurel32
Date: 2016-07-06 21:16:54 +0000 (Wed, 06 Jul 2016)
New Revision: 6080

Modified:
   trunk/glibc-ports-2.24/fbtl/pthread_mutex_unlock.c
   trunk/glibc-ports-2.24/kfreebsd/fbtl/lowlevellock.h
Log:
Merge from upstream:

commit 389fdf78b2e606387ce9d51f29e5c0a22ad9ad2a
Author: Torvald Riegel <triegel at redhat.com>
Date:   Tue Jul 14 21:58:34 2015 +0200

    Do not violate mutex destruction requirements.

    POSIX and C++11 require that a thread can destroy a mutex if no other
    thread owns the mutex, is blocked on the mutex, or will try to acquire
    it in the future.  After destroying the mutex, it can reuse or unmap the
    underlying memory.  Thus, we must not access a mutex' memory after
    releasing it.  Currently, we can load the private flag after releasing
    the mutex, which is fixed by this patch.
    See https://sourceware.org/bugzilla/show_bug.cgi?id=13690 for more
    background.

    We need to call futex_wake on the lock after releasing it, however.  This
    is by design, and can lead to spurious wake-ups on unrelated futex words
    (e.g., when the mutex memory is reused for another mutex).  This behavior
    is documented in the glibc-internal futex API and in recent drafts of the
    Linux kernel's futex documentation (see the draft_futex branch of
    git://git.kernel.org/pub/scm/docs/man-pages/man-pages.git).



Modified: trunk/glibc-ports-2.24/fbtl/pthread_mutex_unlock.c
===================================================================
--- trunk/glibc-ports-2.24/fbtl/pthread_mutex_unlock.c	2016-07-06 20:43:16 UTC (rev 6079)
+++ trunk/glibc-ports-2.24/fbtl/pthread_mutex_unlock.c	2016-07-06 21:16:54 UTC (rev 6080)
@@ -216,16 +216,18 @@
 	/* One less user.  */
 	--mutex->__data.__nusers;
 
-      /* Unlock.  */
+      /* Unlock.  Load all necessary mutex data before releasing the mutex
+	 to not violate the mutex destruction requirements (see
+	 lll_unlock).  */
+      int robust = mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP;
+      int private = (robust
+		     ? PTHREAD_ROBUST_MUTEX_PSHARED (mutex)
+		     : PTHREAD_MUTEX_PSHARED (mutex));
       if ((mutex->__data.__lock & FUTEX_WAITERS) != 0
 	  || atomic_compare_and_exchange_bool_rel (&mutex->__data.__lock, 0,
 						   THREAD_GETMEM (THREAD_SELF,
 								  tid)))
 	{
-	  int robust = mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP;
-	  int private = (robust
-			 ? PTHREAD_ROBUST_MUTEX_PSHARED (mutex)
-			 : PTHREAD_MUTEX_PSHARED (mutex));
 	  INTERNAL_SYSCALL_DECL (__err);
 	  INTERNAL_SYSCALL (futex, __err, 2, &mutex->__data.__lock,
 			    __lll_private_flag (FUTEX_UNLOCK_PI, private));

Modified: trunk/glibc-ports-2.24/kfreebsd/fbtl/lowlevellock.h
===================================================================
--- trunk/glibc-ports-2.24/kfreebsd/fbtl/lowlevellock.h	2016-07-06 20:43:16 UTC (rev 6079)
+++ trunk/glibc-ports-2.24/kfreebsd/fbtl/lowlevellock.h	2016-07-06 21:16:54 UTC (rev 6080)
@@ -128,9 +128,10 @@
 #define __lll_unlock(futex, private) \
   (void)							\
     ({ int *__futex = (futex);					\
+       int __private = (private);				\
        int __oldval = atomic_exchange_rel (__futex, 0);		\
        if (__builtin_expect (__oldval > 1, 0))			\
-	 lll_futex_wake (__futex, 1, private);			\
+	 lll_futex_wake (__futex, 1, __private);		\
     })
     
 #define lll_unlock(futex, private) __lll_unlock(&(futex), private)




More information about the Glibc-bsd-commits mailing list