1/* Copyright (C) 2002, 2003, 2005, 2007, 2009 Free Software Foundation, Inc. 2 This file is part of the GNU C Library. 3 Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. 4 5 The GNU C Library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 The GNU C Library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with the GNU C Library; if not, see 17 <http://www.gnu.org/licenses/>. */ 18 19#include <sysdep.h> 20#include <lowlevellock.h> 21#include <lowlevelrwlock.h> 22#include <bits/kernel-features.h> 23 24 25 .text 26 27 .globl __pthread_rwlock_unlock 28 .type __pthread_rwlock_unlock,@function 29 .protected __pthread_rwlock_unlock 30 .align 16 31__pthread_rwlock_unlock: 32 cfi_startproc 33 /* Get the lock. */ 34 movl $1, %esi 35 xorl %eax, %eax 36 LOCK 37#if MUTEX == 0 38 cmpxchgl %esi, (%rdi) 39#else 40 cmpxchgl %esi, MUTEX(%rdi) 41#endif 42 jnz 1f 43 442: cmpl $0, WRITER(%rdi) 45 jne 5f 46 decl NR_READERS(%rdi) 47 jnz 6f 48 495: movl $0, WRITER(%rdi) 50 51 movl $1, %edx 52 leaq WRITERS_WAKEUP(%rdi), %r10 53 cmpl $0, WRITERS_QUEUED(%rdi) 54 jne 0f 55 56 /* If also no readers waiting nothing to do. */ 57 cmpl $0, READERS_QUEUED(%rdi) 58 je 6f 59 60 movl $0x7fffffff, %edx 61 leaq READERS_WAKEUP(%rdi), %r10 62 630: incl (%r10) 64 LOCK 65#if MUTEX == 0 66 decl (%rdi) 67#else 68 decl MUTEX(%rdi) 69#endif 70 jne 7f 71 728: 73#ifdef __ASSUME_PRIVATE_FUTEX 74 movl $FUTEX_PRIVATE_FLAG|FUTEX_WAKE, %esi 75 xorl PSHARED(%rdi), %esi 76#else 77 movl $FUTEX_WAKE, %esi 78 orl PSHARED(%rdi), %esi 79 xorl %fs:PRIVATE_FUTEX, %esi 80#endif 81 movl $SYS_futex, %eax 82 movq %r10, %rdi 83 syscall 84 85 xorl %eax, %eax 86 retq 87 88 .align 16 896: LOCK 90#if MUTEX == 0 91 decl (%rdi) 92#else 93 decl MUTEX(%rdi) 94#endif 95 jne 3f 96 974: xorl %eax, %eax 98 retq 99 1001: movl PSHARED(%rdi), %esi 101#if MUTEX != 0 102 addq $MUTEX, %rdi 103#endif 104 callq __lll_lock_wait 105#if MUTEX != 0 106 subq $MUTEX, %rdi 107#endif 108 jmp 2b 109 1103: movl PSHARED(%rdi), %esi 111#if MUTEX != 0 112 addq $MUTEX, %rdi 113#endif 114 callq __lll_unlock_wake 115 jmp 4b 116 1177: movl PSHARED(%rdi), %esi 118#if MUTEX != 0 119 addq $MUTEX, %rdi 120#endif 121 callq __lll_unlock_wake 122 jmp 8b 123 cfi_endproc 124 .size __pthread_rwlock_unlock,.-__pthread_rwlock_unlock 125 126 .globl pthread_rwlock_unlock 127pthread_rwlock_unlock = __pthread_rwlock_unlock 128 129 .globl __pthread_rwlock_unlock_internal 130__pthread_rwlock_unlock_internal = __pthread_rwlock_unlock 131