Fix bookkeeping in mutex when using requeue_pi.
authorUlrich Drepper <drepper@redhat.com>
Tue, 28 Jul 2009 16:40:39 +0000 (09:40 -0700)
committerUlrich Drepper <drepper@redhat.com>
Tue, 28 Jul 2009 16:40:39 +0000 (09:40 -0700)
nptl/ChangeLog
nptl/pthreadP.h
nptl/pthread_mutex_lock.c
nptl/pthread_mutex_unlock.c
nptl/sysdeps/unix/sysv/linux/pthread-pi-defines.sym
nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S
nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S
nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S

index 8dd9373..8f37da7 100644 (file)
@@ -1,3 +1,20 @@
+2009-07-28  Ulrich Drepper  <drepper@redhat.com>
+
+       * pthread_mutex_lock.c [NO_INCR] (__pthread_mutex_cond_lock_adjust):
+       New function.
+       * pthreadP.h: Declare __pthread_mutex_cond_lock_adjust.
+       * sysdeps/unix/sysv/linux/pthread-pi-defines.sym: Add ROBUST_BIT.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S: Don't use
+       requeue_pi for robust mutexes.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S: Likewise.
+       Don't only skip __pthread_mutex_cond_lock.  Call instead
+       __pthread_mutex_cond_lock_adjust.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S: Likewise.
+
+       * pthread_mutex_unlock.c (__pthread_mutex_unlock_full): Minor
+       optimization of PI mutex handling.
+
 2009-07-27  Ulrich Drepper  <drepper@redhat.com>
 
        [BZ #10418]
index ed9fc62..43ca44c 100644 (file)
@@ -418,6 +418,8 @@ extern int __pthread_mutex_lock_internal (pthread_mutex_t *__mutex)
      attribute_hidden;
 extern int __pthread_mutex_cond_lock (pthread_mutex_t *__mutex)
      attribute_hidden internal_function;
+extern void __pthread_mutex_cond_lock_adjust (pthread_mutex_t *__mutex)
+     attribute_hidden internal_function;
 extern int __pthread_mutex_unlock (pthread_mutex_t *__mutex);
 extern int __pthread_mutex_unlock_internal (pthread_mutex_t *__mutex)
      attribute_hidden;
index 406e588..50dc188 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002-2007, 2008 Free Software Foundation, Inc.
+/* Copyright (C) 2002-2007, 2008, 2009 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -473,3 +473,22 @@ __pthread_mutex_lock_full (pthread_mutex_t *mutex)
 strong_alias (__pthread_mutex_lock, pthread_mutex_lock)
 strong_alias (__pthread_mutex_lock, __pthread_mutex_lock_internal)
 #endif
+
+
+#ifdef NO_INCR
+void
+__pthread_mutex_cond_lock_adjust (mutex)
+     pthread_mutex_t *mutex;
+{
+  assert ((mutex->__data.__kind & PTHREAD_MUTEX_PRIO_INHERIT_NP) != 0);
+  assert ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) == 0);
+  assert ((mutex->__data.__kind & PTHREAD_MUTEX_PSHARED_BIT) == 0);
+
+  /* Record the ownership.  */
+  pid_t id = THREAD_GETMEM (THREAD_SELF, tid);
+  mutex->__data.__owner = id;
+
+  if (mutex->__data.__kind == PTHREAD_MUTEX_PI_RECURSIVE_NP)
+    ++mutex->__data.__count;
+}
+#endif
index fbe8274..f9fe10b 100644 (file)
@@ -150,7 +150,7 @@ __pthread_mutex_unlock_full (pthread_mutex_t *mutex, int decr)
       if (--mutex->__data.__count != 0)
        /* We still hold the mutex.  */
        return 0;
-      goto continue_pi;
+      goto continue_pi_non_robust;
 
     case PTHREAD_MUTEX_PI_ROBUST_RECURSIVE_NP:
       /* Recursive mutex.  */
@@ -173,7 +173,7 @@ __pthread_mutex_unlock_full (pthread_mutex_t *mutex, int decr)
        /* We still hold the mutex.  */
        return 0;
 
-      goto continue_pi;
+      goto continue_pi_robust;
 
     case PTHREAD_MUTEX_PI_ERRORCHECK_NP:
     case PTHREAD_MUTEX_PI_NORMAL_NP:
@@ -195,9 +195,9 @@ __pthread_mutex_unlock_full (pthread_mutex_t *mutex, int decr)
       pi_notrecoverable:
        newowner = PTHREAD_MUTEX_NOTRECOVERABLE;
 
-    continue_pi:
       if ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) != 0)
        {
+       continue_pi_robust:
          /* Remove mutex from the list.
             Note: robust PI futexes are signaled by setting bit 0.  */
          THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
@@ -206,6 +206,7 @@ __pthread_mutex_unlock_full (pthread_mutex_t *mutex, int decr)
          DEQUEUE_MUTEX (mutex);
        }
 
+    continue_pi_non_robust:
       mutex->__data.__owner = newowner;
       if (decr)
        /* One less user.  */
index d985c6a..46fbd0d 100644 (file)
@@ -3,5 +3,6 @@
 -- These PI macros are used by assembly code.
 
 MUTEX_KIND     offsetof (pthread_mutex_t, __data.__kind)
+ROBUST_BIT     PTHREAD_MUTEX_ROBUST_NORMAL_NP
 PI_BIT         PTHREAD_MUTEX_PRIO_INHERIT_NP
 PS_BIT         PTHREAD_MUTEX_PSHARED_BIT
index 0f10ec9..224a560 100644 (file)
@@ -75,8 +75,10 @@ __pthread_cond_broadcast:
        jne     9f
 
        /* Requeue to a PI mutex if the PI bit is set.  */
-       testl   $PI_BIT, MUTEX_KIND(%r8)
-       jne     81f
+       movl    MUTEX_KIND(%r8), %eax
+       andl    $(ROBUST_BIT|PI_BIT), %eax
+       cmpl    $PI_BIT, %eax
+       je      81f
 
        /* Wake up all threads.  */
 #ifdef __ASSUME_PRIVATE_FUTEX
index f1050fe..4d001ee 100644 (file)
@@ -64,8 +64,10 @@ __pthread_cond_signal:
 
        /* Get the address of the mutex used.  */
        movq    dep_mutex(%r8), %rcx
-       testl   $PI_BIT, MUTEX_KIND(%rcx)
-       jne     9f
+       movl    MUTEX_KIND(%rcx), %eax
+       andl    $(ROBUST_BIT|PI_BIT), %eax
+       cmpl    $PI_BIT, %eax
+       je      9f
 
 #ifdef __ASSUME_PRIVATE_FUTEX
        movl    $(FUTEX_WAKE_OP|FUTEX_PRIVATE_FLAG), %esi
index 7486825..4913beb 100644 (file)
@@ -165,9 +165,12 @@ __pthread_cond_timedwait:
        je      60f
 
        movq    dep_mutex(%rdi), %r8
-       /* Requeue to a PI mutex if the PI bit is set.  */
-       testl   $PI_BIT, MUTEX_KIND(%r8)
-       je      61f
+       /* Requeue to a non-robust PI mutex if the PI bit is set and
+       the robust bit is not set.  */
+       movl    MUTEX_KIND(%r8), %eax
+       andl    $(ROBUST_BIT|PI_BIT), %eax
+       cmpl    $PI_BIT, %eax
+       jne     61f
 
        movl    $(FUTEX_WAIT_REQUEUE_PI|FUTEX_PRIVATE_FLAG), %esi
        xorl    %eax, %eax
@@ -289,11 +292,10 @@ __pthread_cond_timedwait:
 
        /* If requeue_pi is used the kernel performs the locking of the
           mutex. */
-41:    xorl    %eax, %eax
+41:    movq    16(%rsp), %rdi
        testl   %r15d, %r15d
-       jnz     63f
+       jnz     64f
 
-       movq    16(%rsp), %rdi
        callq   __pthread_mutex_cond_lock
 
 63:    testq   %rax, %rax
@@ -316,12 +318,18 @@ __pthread_cond_timedwait:
 
        retq
 
-       /* Initial locking failed.  */
-31:    cfi_adjust_cfa_offset(4 * 8 + FRAME_SIZE)
+       cfi_adjust_cfa_offset(4 * 8 + FRAME_SIZE)
        cfi_rel_offset(%r12, FRAME_SIZE + 24)
        cfi_rel_offset(%r13, FRAME_SIZE + 16)
        cfi_rel_offset(%r14, FRAME_SIZE + 8)
        cfi_rel_offset(%r15, FRAME_SIZE)
+
+64:    callq   __pthread_mutex_cond_lock_adjust
+       movq    %r14, %rax
+       jmp     48b
+
+       /* Initial locking failed.  */
+31:
 #if cond_lock != 0
        addq    $cond_lock, %rdi
 #endif
index 2fab38e..a66523e 100644 (file)
@@ -134,9 +134,12 @@ __pthread_cond_wait:
        je      60f
 
        movq    dep_mutex-cond_futex(%rdi), %r8
-       /* Requeue to a PI mutex if the PI bit is set.  */
-       testl   $PI_BIT, MUTEX_KIND(%r8)
-       je      61f
+       /* Requeue to a non-robust PI mutex if the PI bit is set and
+       the robust bit is not set.  */
+       movl    MUTEX_KIND(%r8), %eax
+       andl    $(ROBUST_BIT|PI_BIT), %eax
+       cmpl    $PI_BIT, %eax
+       jne     61f
 
        movl    $(FUTEX_WAIT_REQUEUE_PI|FUTEX_PRIVATE_FLAG), %esi
        movl    $SYS_futex, %eax
@@ -234,11 +237,10 @@ __pthread_cond_wait:
 
        /* If requeue_pi is used the kernel performs the locking of the
           mutex. */
-11:    xorl    %eax, %eax
+11:    movq    16(%rsp), %rdi
        testl   %r13d, %r13d
-       jnz     14f
+       jnz     18f
 
-       movq    16(%rsp), %rdi
        callq   __pthread_mutex_cond_lock
 
 14:    addq    $FRAME_SIZE, %rsp
@@ -254,11 +256,16 @@ __pthread_cond_wait:
        /* We return the result of the mutex_lock operation.  */
        retq
 
-       /* Initial locking failed.  */
-1:
        cfi_adjust_cfa_offset(16 + FRAME_SIZE)
        cfi_rel_offset(%r12, FRAME_SIZE + 8)
        cfi_rel_offset(%r13, FRAME_SIZE)
+
+18:    callq   __pthread_mutex_cond_lock_adjust
+       xorl    %eax, %eax
+       jmp     14b
+
+       /* Initial locking failed.  */
+1:
 #if cond_lock != 0
        addq    $cond_lock, %rdi
 #endif