Fix bookkeeping in mutex when using requeue_pi.

This commit is contained in:
Ulrich Drepper 2009-07-28 09:40:39 -07:00
parent e73e694e38
commit b0948ffdcb
9 changed files with 83 additions and 24 deletions

View 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> 2009-07-27 Ulrich Drepper <drepper@redhat.com>
[BZ #10418] [BZ #10418]

View File

@ -418,6 +418,8 @@ extern int __pthread_mutex_lock_internal (pthread_mutex_t *__mutex)
attribute_hidden; attribute_hidden;
extern int __pthread_mutex_cond_lock (pthread_mutex_t *__mutex) extern int __pthread_mutex_cond_lock (pthread_mutex_t *__mutex)
attribute_hidden internal_function; 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 (pthread_mutex_t *__mutex);
extern int __pthread_mutex_unlock_internal (pthread_mutex_t *__mutex) extern int __pthread_mutex_unlock_internal (pthread_mutex_t *__mutex)
attribute_hidden; attribute_hidden;

View 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. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. 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)
strong_alias (__pthread_mutex_lock, __pthread_mutex_lock_internal) strong_alias (__pthread_mutex_lock, __pthread_mutex_lock_internal)
#endif #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

View File

@ -150,7 +150,7 @@ __pthread_mutex_unlock_full (pthread_mutex_t *mutex, int decr)
if (--mutex->__data.__count != 0) if (--mutex->__data.__count != 0)
/* We still hold the mutex. */ /* We still hold the mutex. */
return 0; return 0;
goto continue_pi; goto continue_pi_non_robust;
case PTHREAD_MUTEX_PI_ROBUST_RECURSIVE_NP: case PTHREAD_MUTEX_PI_ROBUST_RECURSIVE_NP:
/* Recursive mutex. */ /* Recursive mutex. */
@ -173,7 +173,7 @@ __pthread_mutex_unlock_full (pthread_mutex_t *mutex, int decr)
/* We still hold the mutex. */ /* We still hold the mutex. */
return 0; return 0;
goto continue_pi; goto continue_pi_robust;
case PTHREAD_MUTEX_PI_ERRORCHECK_NP: case PTHREAD_MUTEX_PI_ERRORCHECK_NP:
case PTHREAD_MUTEX_PI_NORMAL_NP: case PTHREAD_MUTEX_PI_NORMAL_NP:
@ -195,9 +195,9 @@ __pthread_mutex_unlock_full (pthread_mutex_t *mutex, int decr)
pi_notrecoverable: pi_notrecoverable:
newowner = PTHREAD_MUTEX_NOTRECOVERABLE; newowner = PTHREAD_MUTEX_NOTRECOVERABLE;
continue_pi:
if ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) != 0) if ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) != 0)
{ {
continue_pi_robust:
/* Remove mutex from the list. /* Remove mutex from the list.
Note: robust PI futexes are signaled by setting bit 0. */ Note: robust PI futexes are signaled by setting bit 0. */
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, 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); DEQUEUE_MUTEX (mutex);
} }
continue_pi_non_robust:
mutex->__data.__owner = newowner; mutex->__data.__owner = newowner;
if (decr) if (decr)
/* One less user. */ /* One less user. */

View File

@ -3,5 +3,6 @@
-- These PI macros are used by assembly code. -- These PI macros are used by assembly code.
MUTEX_KIND offsetof (pthread_mutex_t, __data.__kind) MUTEX_KIND offsetof (pthread_mutex_t, __data.__kind)
ROBUST_BIT PTHREAD_MUTEX_ROBUST_NORMAL_NP
PI_BIT PTHREAD_MUTEX_PRIO_INHERIT_NP PI_BIT PTHREAD_MUTEX_PRIO_INHERIT_NP
PS_BIT PTHREAD_MUTEX_PSHARED_BIT PS_BIT PTHREAD_MUTEX_PSHARED_BIT

View File

@ -75,8 +75,10 @@ __pthread_cond_broadcast:
jne 9f jne 9f
/* Requeue to a PI mutex if the PI bit is set. */ /* Requeue to a PI mutex if the PI bit is set. */
testl $PI_BIT, MUTEX_KIND(%r8) movl MUTEX_KIND(%r8), %eax
jne 81f andl $(ROBUST_BIT|PI_BIT), %eax
cmpl $PI_BIT, %eax
je 81f
/* Wake up all threads. */ /* Wake up all threads. */
#ifdef __ASSUME_PRIVATE_FUTEX #ifdef __ASSUME_PRIVATE_FUTEX

View File

@ -64,8 +64,10 @@ __pthread_cond_signal:
/* Get the address of the mutex used. */ /* Get the address of the mutex used. */
movq dep_mutex(%r8), %rcx movq dep_mutex(%r8), %rcx
testl $PI_BIT, MUTEX_KIND(%rcx) movl MUTEX_KIND(%rcx), %eax
jne 9f andl $(ROBUST_BIT|PI_BIT), %eax
cmpl $PI_BIT, %eax
je 9f
#ifdef __ASSUME_PRIVATE_FUTEX #ifdef __ASSUME_PRIVATE_FUTEX
movl $(FUTEX_WAKE_OP|FUTEX_PRIVATE_FLAG), %esi movl $(FUTEX_WAKE_OP|FUTEX_PRIVATE_FLAG), %esi

View File

@ -165,9 +165,12 @@ __pthread_cond_timedwait:
je 60f je 60f
movq dep_mutex(%rdi), %r8 movq dep_mutex(%rdi), %r8
/* Requeue to a PI mutex if the PI bit is set. */ /* Requeue to a non-robust PI mutex if the PI bit is set and
testl $PI_BIT, MUTEX_KIND(%r8) the robust bit is not set. */
je 61f 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 $(FUTEX_WAIT_REQUEUE_PI|FUTEX_PRIVATE_FLAG), %esi
xorl %eax, %eax xorl %eax, %eax
@ -289,11 +292,10 @@ __pthread_cond_timedwait:
/* If requeue_pi is used the kernel performs the locking of the /* If requeue_pi is used the kernel performs the locking of the
mutex. */ mutex. */
41: xorl %eax, %eax 41: movq 16(%rsp), %rdi
testl %r15d, %r15d testl %r15d, %r15d
jnz 63f jnz 64f
movq 16(%rsp), %rdi
callq __pthread_mutex_cond_lock callq __pthread_mutex_cond_lock
63: testq %rax, %rax 63: testq %rax, %rax
@ -316,12 +318,18 @@ __pthread_cond_timedwait:
retq retq
/* Initial locking failed. */ cfi_adjust_cfa_offset(4 * 8 + FRAME_SIZE)
31: cfi_adjust_cfa_offset(4 * 8 + FRAME_SIZE)
cfi_rel_offset(%r12, FRAME_SIZE + 24) cfi_rel_offset(%r12, FRAME_SIZE + 24)
cfi_rel_offset(%r13, FRAME_SIZE + 16) cfi_rel_offset(%r13, FRAME_SIZE + 16)
cfi_rel_offset(%r14, FRAME_SIZE + 8) cfi_rel_offset(%r14, FRAME_SIZE + 8)
cfi_rel_offset(%r15, FRAME_SIZE) 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 #if cond_lock != 0
addq $cond_lock, %rdi addq $cond_lock, %rdi
#endif #endif

View File

@ -134,9 +134,12 @@ __pthread_cond_wait:
je 60f je 60f
movq dep_mutex-cond_futex(%rdi), %r8 movq dep_mutex-cond_futex(%rdi), %r8
/* Requeue to a PI mutex if the PI bit is set. */ /* Requeue to a non-robust PI mutex if the PI bit is set and
testl $PI_BIT, MUTEX_KIND(%r8) the robust bit is not set. */
je 61f 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 $(FUTEX_WAIT_REQUEUE_PI|FUTEX_PRIVATE_FLAG), %esi
movl $SYS_futex, %eax movl $SYS_futex, %eax
@ -234,11 +237,10 @@ __pthread_cond_wait:
/* If requeue_pi is used the kernel performs the locking of the /* If requeue_pi is used the kernel performs the locking of the
mutex. */ mutex. */
11: xorl %eax, %eax 11: movq 16(%rsp), %rdi
testl %r13d, %r13d testl %r13d, %r13d
jnz 14f jnz 18f
movq 16(%rsp), %rdi
callq __pthread_mutex_cond_lock callq __pthread_mutex_cond_lock
14: addq $FRAME_SIZE, %rsp 14: addq $FRAME_SIZE, %rsp
@ -254,11 +256,16 @@ __pthread_cond_wait:
/* We return the result of the mutex_lock operation. */ /* We return the result of the mutex_lock operation. */
retq retq
/* Initial locking failed. */
1:
cfi_adjust_cfa_offset(16 + FRAME_SIZE) cfi_adjust_cfa_offset(16 + FRAME_SIZE)
cfi_rel_offset(%r12, FRAME_SIZE + 8) cfi_rel_offset(%r12, FRAME_SIZE + 8)
cfi_rel_offset(%r13, FRAME_SIZE) 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 #if cond_lock != 0
addq $cond_lock, %rdi addq $cond_lock, %rdi
#endif #endif