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 <pthread-errnos.h> 23#include <bits/kernel-features.h> 24#include <tcb-offsets.h> 25 26 27 .text 28 29 .globl __pthread_rwlock_wrlock 30 .type __pthread_rwlock_wrlock,@function 31 .protected __pthread_rwlock_wrlock 32 .align 16 33__pthread_rwlock_wrlock: 34 cfi_startproc 35 xorq %r10, %r10 36 37 /* Get the lock. */ 38 movl $1, %esi 39 xorl %eax, %eax 40 LOCK 41#if MUTEX == 0 42 cmpxchgl %esi, (%rdi) 43#else 44 cmpxchgl %esi, MUTEX(%rdi) 45#endif 46 jnz 1f 47 482: movl WRITER(%rdi), %eax 49 testl %eax, %eax 50 jne 14f 51 cmpl $0, NR_READERS(%rdi) 52 je 5f 53 543: incl WRITERS_QUEUED(%rdi) 55 je 4f 56 57 movl WRITERS_WAKEUP(%rdi), %edx 58 59 LOCK 60#if MUTEX == 0 61 decl (%rdi) 62#else 63 decl MUTEX(%rdi) 64#endif 65 jne 10f 66 6711: 68#ifdef __ASSUME_PRIVATE_FUTEX 69 movl $FUTEX_PRIVATE_FLAG|FUTEX_WAIT, %esi 70 xorl PSHARED(%rdi), %esi 71#else 72# if FUTEX_WAIT == 0 73 movl PSHARED(%rdi), %esi 74# else 75 movl $FUTEX_WAIT, %esi 76 orl PSHARED(%rdi), %esi 77# endif 78 xorl %fs:PRIVATE_FUTEX, %esi 79#endif 80 addq $WRITERS_WAKEUP, %rdi 81 movl $SYS_futex, %eax 82 syscall 83 84 subq $WRITERS_WAKEUP, %rdi 85 86 /* Reget the lock. */ 87 movl $1, %esi 88 xorl %eax, %eax 89 LOCK 90#if MUTEX == 0 91 cmpxchgl %esi, (%rdi) 92#else 93 cmpxchgl %esi, MUTEX(%rdi) 94#endif 95 jnz 12f 96 9713: decl WRITERS_QUEUED(%rdi) 98 jmp 2b 99 1005: xorl %edx, %edx 101 movl %fs:TID, %eax 102 movl %eax, WRITER(%rdi) 1039: LOCK 104#if MUTEX == 0 105 decl (%rdi) 106#else 107 decl MUTEX(%rdi) 108#endif 109 jne 6f 1107: 111 112 movq %rdx, %rax 113 retq 114 1151: movl PSHARED(%rdi), %esi 116#if MUTEX != 0 117 addq $MUTEX, %rdi 118#endif 119 callq __lll_lock_wait 120#if MUTEX != 0 121 subq $MUTEX, %rdi 122#endif 123 jmp 2b 124 12514: cmpl %fs:TID, %eax 126 jne 3b 127 movl $EDEADLK, %edx 128 jmp 9b 129 1306: movl PSHARED(%rdi), %esi 131#if MUTEX != 0 132 addq $MUTEX, %rdi 133#endif 134 callq __lll_unlock_wake 135 jmp 7b 136 1374: decl WRITERS_QUEUED(%rdi) 138 movl $EAGAIN, %edx 139 jmp 9b 140 14110: movl PSHARED(%rdi), %esi 142#if MUTEX != 0 143 addq $MUTEX, %rdi 144#endif 145 callq __lll_unlock_wake 146#if MUTEX != 0 147 subq $MUTEX, %rdi 148#endif 149 jmp 11b 150 15112: movl PSHARED(%rdi), %esi 152#if MUTEX != 0 153 addq $MUTEX, %rdi 154#endif 155 callq __lll_lock_wait 156#if MUTEX != 0 157 subq $MUTEX, %rdi 158#endif 159 jmp 13b 160 cfi_endproc 161 .size __pthread_rwlock_wrlock,.-__pthread_rwlock_wrlock 162 163 .globl pthread_rwlock_wrlock 164pthread_rwlock_wrlock = __pthread_rwlock_wrlock 165 166 .globl __pthread_rwlock_wrlock_internal 167__pthread_rwlock_wrlock_internal = __pthread_rwlock_wrlock 168