diff options
author | Andreas Schwab <schwab@redhat.com> | 2009-08-22 02:01:51 -0700 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2009-08-22 02:01:51 -0700 |
commit | 15efafdf07789322219cc8f938ac758f932fe208 (patch) | |
tree | 30e249a3b3fed95c18c78e7bffb260d361f9abb6 /nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S | |
parent | 464dc022eb0be4950e2f3a90fe4de6a17dc3d7d7 (diff) |
Add sigstack handling to Linux ____longjmp_chk on powerpc.
Diffstat (limited to 'nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S')
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S index 03391d0fc2..1953637055 100644 --- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S +++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S @@ -30,6 +30,97 @@ .align 16 __pthread_rwlock_unlock: cfi_startproc + movq NRW_WORD(%rdi), %rax + movq $NRW_WL, %rdx + testq %rdx, %rax + jnz .Lunlock_writer + +.Lagain: + movq $-NRW_RC, %rdx + addq %rax, %rdx + movq $NRW_RC_MASK, %rcx + testq %rcx, %rdx + jz .Llast_reader + +1: LOCK + cmpxchgq %rdx, NRW_WORD(%rdi) + jnz .Lagain + + xorl %eax, %eax + ret + +.Llast_reader: + movq $NRW_WW_MASK, %rcx + testq %rax, %rcx + jz 1b + + movq $NRW_AR, %rcx + xorl %esi, %esi + testq $NRW_WP, %rax + cmovz %esi, %ecx + orq %rcx, %rdx + LOCK + cmpxchgq %rdx, NRW_WORD(%rdi) + jnz .Lagain + +.Lwake_writer: + movl $1, %edx + movl $NRW_W_WAKEUP, %r9d +.Lwake: movl $(FUTEX_WAKE_BITSET|FUTEX_PRIVATE_FLAG), %esi + xorl PSHARED(%rdi), %esi + leaq NRW_WORD(%rdi), %rdi + movl $__NR_futex, %eax + syscall + +.Lout: xorl %eax, %eax + ret + +.Lunlock_writer: + movq %rax, %rdx + movq $NRW_WW_MASK, %rcx + testq %rcx, %rax + jz .Lno_writers + movq $NRW_RC_MASK, %rcx + testq %rcx, %rax + jz 2f + testq $NRW_WP, %rax + jz .Lwake_readers + +2: movq $~NRW_WL, %rcx + andq %rcx, %rdx + LOCK + cmpxchgq %rdx, NRW_WORD(%rdi) + jnz .Lunlock_writer + jmp .Lwake_writer + +.Lno_writers: + movq $~(NRW_WL|NRW_AR), %rcx + andq %rcx, %rdx + LOCK + cmpxchgq %rdx, NRW_WORD(%rdi) + jnz .Lunlock_writer + + movq $(NRW_RW_MASK|NRW_RC_MASK), %rcx + testq %rcx, %rax + jz .Lout + + movl $0x7fffffff, %edx + movl $NRW_R_WAKEUP, %r9d + jmp .Lwake + +.Lwake_readers: + movq $~NRW_WL, %rcx + andq %rcx, %rdx + LOCK + cmpxchgq %rdx, NRW_WORD(%rdi) + jnz .Lunlock_writer + + movl $0x7fffffff, %edx + movl $NRW_R_WAKEUP, %r9d + jmp .Lwake + + +#if 0 /* Get the lock. */ movl $1, %esi xorl %eax, %eax @@ -120,6 +211,7 @@ __pthread_rwlock_unlock: #endif callq __lll_unlock_wake jmp 8b +#endif cfi_endproc .size __pthread_rwlock_unlock,.-__pthread_rwlock_unlock |