2.5-18.1
[glibc.git] / nptl / sysdeps / unix / sysv / linux / x86_64 / pthread_rwlock_wrlock.S
blob0e82f890aaf2437baaae078cfc00e66e8f346955
1 /* Copyright (C) 2002, 2003, 2005 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 <lowlevelrwlock.h>
22 #include <pthread-errnos.h>
25 #define SYS_futex               202
26 #define FUTEX_WAIT              0
27 #define FUTEX_WAKE              1
29 #ifndef UP
30 # define LOCK lock
31 #else
32 # define LOCK
33 #endif
36         .text
38         .globl  __pthread_rwlock_wrlock
39         .type   __pthread_rwlock_wrlock,@function
40         .align  16
41 __pthread_rwlock_wrlock:
42         xorq    %r10, %r10
44         /* Get the lock.  */
45         movl    $1, %esi
46         xorl    %eax, %eax
47         LOCK
48 #if MUTEX == 0
49         cmpxchgl %esi, (%rdi)
50 #else
51         cmpxchgl %esi, MUTEX(%rdi)
52 #endif
53         jnz     1f
55 2:      movl    WRITER(%rdi), %eax
56         testl   %eax, %eax
57         jne     14f
58         cmpl    $0, NR_READERS(%rdi)
59         je      5f
61 3:      incl    WRITERS_QUEUED(%rdi)
62         je      4f
64         movl    WRITERS_WAKEUP(%rdi), %edx
66         LOCK
67 #if MUTEX == 0
68         decl    (%rdi)
69 #else
70         decl    MUTEX(%rdi)
71 #endif
72         jne     10f
74 11:     addq    $WRITERS_WAKEUP, %rdi
75 #if FUTEX_WAIT == 0
76         xorl    %esi, %esi
77 #else
78         movl    $FUTEX_WAIT, %esi
79 #endif
80         movl    $SYS_futex, %eax
81         syscall
83         subq    $WRITERS_WAKEUP, %rdi
85         /* Reget the lock.  */
86         movl    $1, %esi
87         xorl    %eax, %eax
88         LOCK
89 #if MUTEX == 0
90         cmpxchgl %esi, (%rdi)
91 #else
92         cmpxchgl %esi, MUTEX(%rdi)
93 #endif
94         jnz     12f
96 13:     decl    WRITERS_QUEUED(%rdi)
97         jmp     2b
99 5:      xorl    %edx, %edx
100         movl    %fs:TID, %eax
101         movl    %eax, WRITER(%rdi)
102 9:      LOCK
103 #if MUTEX == 0
104         decl    (%rdi)
105 #else
106         decl    MUTEX(%rdi)
107 #endif
108         jne     6f
111         movq    %rdx, %rax
112         retq
115 #if MUTEX != 0
116         addq    $MUTEX, %rdi
117 #endif
118         callq   __lll_mutex_lock_wait
119 #if MUTEX != 0
120         subq    $MUTEX, %rdi
121 #endif
122         jmp     2b
124 14:     cmpl    %fs:TID, %eax
125         jne     3b
126         movl    $EDEADLK, %edx
127         jmp     9b
130 #if MUTEX != 0
131         addq    $MUTEX, %rdi
132 #endif
133         callq   __lll_mutex_unlock_wake
134         jmp     7b
136 4:      decl    WRITERS_QUEUED(%rdi)
137         movl    $EAGAIN, %edx
138         jmp     9b
141 #if MUTEX != 0
142         addq    $MUTEX, %rdi
143 #endif
144         callq   __lll_mutex_unlock_wake
145 #if MUTEX != 0
146         subq    $MUTEX, %rdi
147 #endif
148         jmp     11b
151 #if MUTEX != 0
152         addq    $MUTEX, %rdi
153 #endif
154         callq   __lll_mutex_lock_wait
155 #if MUTEX != 0
156         subq    $MUTEX, %rdi
157 #endif
158         jmp     13b
159         .size   __pthread_rwlock_wrlock,.-__pthread_rwlock_wrlock
161         .globl  pthread_rwlock_wrlock
162 pthread_rwlock_wrlock = __pthread_rwlock_wrlock
164         .globl  __pthread_rwlock_wrlock_internal
165 __pthread_rwlock_wrlock_internal = __pthread_rwlock_wrlock