Skip to content

Commit

Permalink
Fix bookkeeping in mutex when using requeue_pi.
Browse files Browse the repository at this point in the history
  • Loading branch information
Ulrich Drepper committed Jul 28, 2009
1 parent e73e694 commit b0948ff
Show file tree
Hide file tree
Showing 9 changed files with 83 additions and 24 deletions.
17 changes: 17 additions & 0 deletions nptl/ChangeLog
Original file line number Diff line number Diff line change
@@ -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]
Expand Down
2 changes: 2 additions & 0 deletions nptl/pthreadP.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
21 changes: 20 additions & 1 deletion nptl/pthread_mutex_lock.c
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -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
7 changes: 4 additions & 3 deletions nptl/pthread_mutex_unlock.c
Original file line number Diff line number Diff line change
Expand Up @@ -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. */
Expand All @@ -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:
Expand All @@ -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,
Expand All @@ -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. */
Expand Down
1 change: 1 addition & 0 deletions nptl/sysdeps/unix/sysv/linux/pthread-pi-defines.sym
Original file line number Diff line number Diff line change
Expand Up @@ -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
6 changes: 4 additions & 2 deletions nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 4 additions & 2 deletions nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
24 changes: 16 additions & 8 deletions nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
23 changes: 15 additions & 8 deletions nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down

0 comments on commit b0948ff

Please sign in to comment.