From c5a0802a682dba23f92d47f0f99775aebfbe2539 Mon Sep 17 00:00:00 2001 From: Andreas Schwab Date: Mon, 28 Nov 2011 13:38:19 +0100 Subject: Handle EAGAIN from FUTEX_WAIT_REQUEUE_PI --- .../unix/sysv/linux/x86_64/pthread_cond_wait.S | 76 +++++++++++++++++++++- 1 file changed, 74 insertions(+), 2 deletions(-) (limited to 'nptl/sysdeps/unix/sysv/linux/x86_64') diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S index 7535baa786..d837d158a4 100644 --- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S +++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S @@ -23,6 +23,7 @@ #include #include #include +#include #include @@ -133,11 +134,14 @@ __pthread_cond_wait: cmpl $PI_BIT, %eax jne 61f +90: movl $(FUTEX_WAIT_REQUEUE_PI|FUTEX_PRIVATE_FLAG), %esi movl $SYS_futex, %eax syscall movl $1, %r8d + cmpq $-EAGAIN, %rax + je 91f #ifdef __ASSUME_REQUEUE_PI jmp 62f #else @@ -324,6 +328,70 @@ __pthread_cond_wait: 13: movq %r10, %rax jmp 14b + +91: +.LcleanupSTART2: + /* FUTEX_WAIT_REQUEUE_PI returned EAGAIN. We need to + call it again. */ + movq 8(%rsp), %rdi + + /* Get internal lock. */ + movl $1, %esi + xorl %eax, %eax + LOCK +#if cond_lock == 0 + cmpxchgl %esi, (%rdi) +#else + cmpxchgl %esi, cond_lock(%rdi) +#endif + jz 92f + +#if cond_lock != 0 + addq $cond_lock, %rdi +#endif + cmpq $-1, dep_mutex-cond_lock(%rdi) + movl $LLL_PRIVATE, %eax + movl $LLL_SHARED, %esi + cmovne %eax, %esi + callq __lll_lock_wait +#if cond_lock != 0 + subq $cond_lock, %rdi +#endif +92: + /* Increment the cond_futex value again, so it can be used as a new + expected value. */ + incl cond_futex(%rdi) + movl cond_futex(%rdi), %edx + + /* Release internal lock. */ + LOCK +#if cond_lock == 0 + decl (%rdi) +#else + decl cond_lock(%rdi) +#endif + jz 93f + +#if cond_lock != 0 + addq $cond_lock, %rdi +#endif + cmpq $-1, dep_mutex-cond_lock(%rdi) + movl $LLL_PRIVATE, %eax + movl $LLL_SHARED, %esi + cmovne %eax, %esi + /* The call preserves %rdx. */ + callq __lll_unlock_wake +#if cond_lock != 0 + subq $cond_lock, %rdi +#endif +93: + /* Set the rest of SYS_futex args for FUTEX_WAIT_REQUEUE_PI. */ + xorq %r10, %r10 + movq dep_mutex(%rdi), %r8 + leaq cond_futex(%rdi), %rdi + jmp 90b +.LcleanupEND2: + .size __pthread_cond_wait, .-__pthread_cond_wait versioned_symbol (libpthread, __pthread_cond_wait, pthread_cond_wait, GLIBC_2_3_2) @@ -476,11 +544,15 @@ __condvar_cleanup1: .uleb128 .LcleanupSTART-.LSTARTCODE .uleb128 .LcleanupEND-.LcleanupSTART .uleb128 __condvar_cleanup1-.LSTARTCODE - .uleb128 0 + .uleb128 0 + .uleb128 .LcleanupSTART2-.LSTARTCODE + .uleb128 .LcleanupEND2-.LcleanupSTART2 + .uleb128 __condvar_cleanup1-.LSTARTCODE + .uleb128 0 .uleb128 .LcallUR-.LSTARTCODE .uleb128 .LENDCODE-.LcallUR .uleb128 0 - .uleb128 0 + .uleb128 0 .Lcstend: -- cgit v1.2.3-70-g09d2