2.9
[glibc/nacl-glibc.git] / nptl / sysdeps / unix / sysv / linux / x86_64 / pthread_rwlock_wrlock.S
blob209c0e9a9492f2fac0c7bf7ea36ede4a2e8cfeb6
1 /* Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
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.
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.
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, write to the Free
17    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18    02111-1307 USA.  */
20 #include <sysdep.h>
21 #include <lowlevellock.h>
22 #include <lowlevelrwlock.h>
23 #include <pthread-errnos.h>
24 #include <kernel-features.h>
27         .text
29         .globl  __pthread_rwlock_wrlock
30         .type   __pthread_rwlock_wrlock,@function
31         .align  16
32 __pthread_rwlock_wrlock:
33         xorq    %r10, %r10
35         /* Get the lock.  */
36         movl    $1, %esi
37         xorl    %eax, %eax
38         LOCK
39 #if MUTEX == 0
40         cmpxchgl %esi, (%rdi)
41 #else
42         cmpxchgl %esi, MUTEX(%rdi)
43 #endif
44         jnz     1f
46 2:      movl    WRITER(%rdi), %eax
47         testl   %eax, %eax
48         jne     14f
49         cmpl    $0, NR_READERS(%rdi)
50         je      5f
52 3:      incl    WRITERS_QUEUED(%rdi)
53         je      4f
55         movl    WRITERS_WAKEUP(%rdi), %edx
57         LOCK
58 #if MUTEX == 0
59         decl    (%rdi)
60 #else
61         decl    MUTEX(%rdi)
62 #endif
63         jne     10f
65 11:
66 #ifdef __ASSUME_PRIVATE_FUTEX
67         movl    $FUTEX_PRIVATE_FLAG|FUTEX_WAIT, %esi
68         xorl    PSHARED(%rdi), %esi
69 #else
70 # if FUTEX_WAIT == 0
71         movl    PSHARED(%rdi), %esi
72 # else
73         movl    $FUTEX_WAIT, %esi
74         orl     PSHARED(%rdi), %esi
75 # endif
76         xorl    %fs:PRIVATE_FUTEX, %esi
77 #endif
78         addq    $WRITERS_WAKEUP, %rdi
79         movl    $SYS_futex, %eax
80         syscall
82         subq    $WRITERS_WAKEUP, %rdi
84         /* Reget the lock.  */
85         movl    $1, %esi
86         xorl    %eax, %eax
87         LOCK
88 #if MUTEX == 0
89         cmpxchgl %esi, (%rdi)
90 #else
91         cmpxchgl %esi, MUTEX(%rdi)
92 #endif
93         jnz     12f
95 13:     decl    WRITERS_QUEUED(%rdi)
96         jmp     2b
98 5:      xorl    %edx, %edx
99         movl    %fs:TID, %eax
100         movl    %eax, WRITER(%rdi)
101 9:      LOCK
102 #if MUTEX == 0
103         decl    (%rdi)
104 #else
105         decl    MUTEX(%rdi)
106 #endif
107         jne     6f
110         movq    %rdx, %rax
111         retq
113 1:      movl    PSHARED(%rdi), %esi
114 #if MUTEX != 0
115         addq    $MUTEX, %rdi
116 #endif
117         callq   __lll_lock_wait
118 #if MUTEX != 0
119         subq    $MUTEX, %rdi
120 #endif
121         jmp     2b
123 14:     cmpl    %fs:TID, %eax
124         jne     3b
125         movl    $EDEADLK, %edx
126         jmp     9b
128 6:      movl    PSHARED(%rdi), %esi
129 #if MUTEX != 0
130         addq    $MUTEX, %rdi
131 #endif
132         callq   __lll_unlock_wake
133         jmp     7b
135 4:      decl    WRITERS_QUEUED(%rdi)
136         movl    $EAGAIN, %edx
137         jmp     9b
139 10:     movl    PSHARED(%rdi), %esi
140 #if MUTEX != 0
141         addq    $MUTEX, %rdi
142 #endif
143         callq   __lll_unlock_wake
144 #if MUTEX != 0
145         subq    $MUTEX, %rdi
146 #endif
147         jmp     11b
149 12:     movl    PSHARED(%rdi), %esi
150 #if MUTEX != 0
151         addq    $MUTEX, %rdi
152 #endif
153         callq   __lll_lock_wait
154 #if MUTEX != 0
155         subq    $MUTEX, %rdi
156 #endif
157         jmp     13b
158         .size   __pthread_rwlock_wrlock,.-__pthread_rwlock_wrlock
160         .globl  pthread_rwlock_wrlock
161 pthread_rwlock_wrlock = __pthread_rwlock_wrlock
163         .globl  __pthread_rwlock_wrlock_internal
164 __pthread_rwlock_wrlock_internal = __pthread_rwlock_wrlock