mirror of
https://sourceware.org/git/glibc.git
synced 2024-12-22 19:00:07 +00:00
Fix bookkeeping in mutex when using requeue_pi.
This commit is contained in:
parent
e73e694e38
commit
b0948ffdcb
@ -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]
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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. */
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user