2003-03-12  Ulrich Drepper  <drepper@redhat.com>

	* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S
	(__pthread_rwlock_timedwrlock): Add missing opcode suffix.
	* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S
	(__pthread_rwlock_timedrdlock): Likewise.
	* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S
	(__pthread_rwlock_wrlock): Likewise.
	* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S
	(__pthread_rwlock_rdlock): Likewise.

	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S: New file.

	* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S: Return
	result of lock re-get if it fails.
This commit is contained in:
Ulrich Drepper 2003-03-12 08:57:35 +00:00
parent a3cd7da30f
commit 35e148cb96
7 changed files with 275 additions and 10 deletions

View file

@ -1,3 +1,19 @@
2003-03-12 Ulrich Drepper <drepper@redhat.com>
* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S
(__pthread_rwlock_timedwrlock): Add missing opcode suffix.
* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S
(__pthread_rwlock_timedrdlock): Likewise.
* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S
(__pthread_rwlock_wrlock): Likewise.
* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S
(__pthread_rwlock_rdlock): Likewise.
* sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S: New file.
* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S: Return
result of lock re-get if it fails.
2003-03-11 Ulrich Drepper <drepper@redhat.com>
* sysdeps/unix/sysv/linux/x86_64/lowlevellock.S: Fix asm syntax.

View file

@ -61,7 +61,7 @@ __pthread_rwlock_rdlock:
2: movl WRITER(%ebx), %eax
testl %eax, %eax
jne 14f
cmp $0, WRITERS_QUEUED(%ebx)
cmpl $0, WRITERS_QUEUED(%ebx)
je 5f
cmpl $0, FLAGS(%ebx)
je 5f

View file

@ -67,7 +67,7 @@ pthread_rwlock_timedrdlock:
2: movl WRITER(%ebp), %eax
testl %eax, %eax
jne 14f
cmp $0, WRITERS_QUEUED(%ebp)
cmpl $0, WRITERS_QUEUED(%ebp)
je 5f
cmpl $0, FLAGS(%ebp)
je 5f

View file

@ -67,7 +67,7 @@ pthread_rwlock_timedwrlock:
2: movl WRITER(%ebp), %eax
testl %eax, %eax
jne 14f
cmp $0, NR_READERS(%ebp)
cmpl $0, NR_READERS(%ebp)
je 5f
/* Check the value of the timeout parameter. */

View file

@ -61,7 +61,7 @@ __pthread_rwlock_wrlock:
2: movl WRITER(%ebx), %eax
testl %eax, %eax
jne 14f
cmp $0, NR_READERS(%ebx)
cmpl $0, NR_READERS(%ebx)
je 5f
3: addl $1, WRITERS_QUEUED(%ebx)

View file

@ -0,0 +1,253 @@
/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <sysdep.h>
#include <shlib-compat.h>
#include <lowlevelcond.h>
#ifdef UP
# define LOCK
#else
# define LOCK lock
#endif
#define SYS_gettimeofday __NR_gettimeofday
#define SYS_futex 202
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
#define ETIMEDOUT 110
.text
/* int pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex,
const struct timespec *abstime) */
.globl __pthread_cond_timedwait
.type __pthread_cond_timedwait, @function
.align 16
__pthread_cond_timedwait:
pushq %r12
pushq %r13
pushq %r14
subq $80, %rsp
/* Prepare structure passed to cancellation handler. */
movq %rdi, 8(%rsp)
movq %rsi, 16(%rsp)
movq %rdx, %r13
/* Get internal lock. */
movl $1, %esi
LOCK
#if cond_lock == 0
xaddl %esi, (%rdi)
#else
xaddl %esi, cond_lock(%rdi)
#endif
testl %esi, %esi
jne 1f
/* Unlock the mutex. */
2: movq 16(%rsp), %rdi
callq __pthread_mutex_unlock_internal
testl %eax, %eax
jne 16f
movq 8(%rsp), %rdi
addq $1, total_seq(%rdi)
/* Install cancellation handler. */
#ifdef PIC
leaq __condvar_cleanup(%rip), %rsi
#else
leaq __condvar_cleanup, %rsi
#endif
leaq 48(%rsp), %rdi
movq %rsp, %rdx
callq __pthread_cleanup_push
/* Get and store current wakeup_seq value. */
movq 8(%rsp), %rdi
movq wakeup_seq(%rdi), %r12
movq %r12, 40(%rsp)
/* Unlock. */
8: LOCK
#if cond_lock == 0
decl (%rdi)
#else
decl cond_lock(%rdi)
#endif
jne 3f
4: movq %rsp, %rdi
call __pthread_enable_asynccancel_2
/* Get the current time. */
leaq 24(%rsp), %rdi
xorq %rcx, %rcx
movq $SYS_gettimeofday, %rax
syscall
/* Compute relative timeout. */
movq 32(%rsp), %rax
movq $1000, %rdx
mul %rdx /* Milli seconds to nano seconds. */
movq (%r13), %rcx
movq 4(%r13), %rdx
subq 24(%rsp), %rcx
subq %rax, %rdx
jns 12f
addq $1000000000, %rdx
decq %rcx
12: testq %rcx, %rcx
js 13f
/* Store relative timeout. */
movq %rcx, 24(%rsp)
movq %rdx, 32(%rsp)
movq 8(%rsp), %rdi
leaq 24(%rsp), %r10
xorq %rsi, %rsi /* movq $FUTEX_WAIT, %rsi */
movq %r12, %rdx
addq $wakeup_seq-cond_lock, %rdi
movq $SYS_futex, %rax
syscall
movq %rax, %r14
movq (%rsp), %rdi
callq __pthread_disable_asynccancel
/* Lock. */
movq 8(%rsp), %rdi
movl $1, %esi
LOCK
#if cond_lock == 0
xaddl %esi, (%rdi)
#else
xaddl %esi, cond_lock(%rdi)
#endif
testl %esi, %esi
jne 5f
6: movq woken_seq(%rdi), %rax
movq wakeup_seq(%rdi), %r12
cmpq 40(%rsp), %rax
jb 15f
cmpq %rax, %r12
ja 9f
15: cmpq $-ETIMEDOUT, %r14
jne 8b
13: incq wakeup_seq(%rdi)
movq $ETIMEDOUT, %rsi
jmp 14f
9: xorq %rsi, %rsi
14: incq woken_seq(%rdi)
LOCK
#if cond_lock == 0
decl (%rdi)
#else
decl cond_lock(%rdi)
#endif
jne 10f
/* Remove cancellation handler. */
11: movq 48+CLEANUP_PREV(%rsp), %rdx
movq %rdx, %fs:CLEANUP
movq 16(%rsp), %rdi
callq __pthread_mutex_lock_internal
testq %rax, %rax
cmoveq %rsi, %rax
18: addq $80, %rsp
popq %r14
popq %r13
popq %r12
retq
/* Initial locking failed. */
1:
#if cond_lock != 0
addq $cond_lock, %rdi
#endif
call __lll_mutex_lock_wait
jmp 2b
/* Unlock in loop requires waekup. */
3:
#if cond_lock != 0
addq $cond_lock, %rdi
#endif
call __lll_mutex_unlock_wake
jmp 4b
/* Locking in loop failed. */
5:
#if cond_lock != 0
addq $cond_lock, %rdi
#endif
call __lll_mutex_lock_wait
#if cond_lock != 0
subq $cond_lock, %rdi
#endif
jmp 6b
/* Unlock after loop requires waekup. */
10:
#if cond_lock != 0
addq $cond_lock, %rdi
#endif
call __lll_mutex_unlock_wake
jmp 11b
/* The initial unlocking of the mutex failed. */
16: movq 8(%rsp), %rdi
movq %rax, (%rsp)
LOCK
#if cond_lock == 0
decl (%rdi)
#else
decl cond_lock(%rdi)
#endif
jne 17f
#if cond_lock != 0
addq $cond_lock, %rdi
#endif
call __lll_mutex_unlock_wake
17: movq (%rsp), %rax
jmp 18b
.size __pthread_cond_wait, .-__pthread_cond_wait
.size __pthread_cond_timedwait, .-__pthread_cond_timedwait
versioned_symbol (libpthread, __pthread_cond_timedwait, pthread_cond_timedwait,
GLIBC_2_3_2)

View file

@ -126,7 +126,7 @@ __pthread_cond_wait:
testl %eax, %eax
jne 12f
movq (%rsp), %rdi
movq 8(%rsp), %rdi
addq $1, total_seq(%rdi)
/* Install cancellation handler. */
@ -163,7 +163,6 @@ __pthread_cond_wait:
movq $SYS_futex, %rax
movq %r10, %rsi /* movl $FUTEX_WAIT, %ecx */
syscall
subl $wakeup_seq-cond_lock, %ebx
movq (%rsp), %rdi
callq __pthread_disable_asynccancel
@ -202,7 +201,7 @@ __pthread_cond_wait:
/* Remove cancellation handler. */
11: movq 32+CLEANUP_PREV(%rsp), %rdx
movq %rdx, %gs:CLEANUP
movq %rdx, %fs:CLEANUP
movq 16(%rsp), %rdi
callq __pthread_mutex_lock_internal
@ -227,9 +226,6 @@ __pthread_cond_wait:
addq $cond_lock, %rdi
#endif
callq __lll_mutex_unlock_wake
#if cond_lock != 0
subq $cond_lock, %rdi
#endif
jmp 4b
/* Locking in loop failed. */