2.5-18.1
[glibc.git] / nptl / sysdeps / unix / sysv / linux / x86_64 / pthread_rwlock_rdlock.S
blob5e9d8fb1d6a6bfe758e75597fa729c4851edc2c8
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_rdlock
39         .type   __pthread_rwlock_rdlock,@function
40         .align  16
41 __pthread_rwlock_rdlock:
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, WRITERS_QUEUED(%rdi)
59         je      5f
60         cmpl    $0, FLAGS(%rdi)
61         je      5f
63 3:      incl    READERS_QUEUED(%rdi)
64         je      4f
66         movl    READERS_WAKEUP(%rdi), %edx
68         LOCK
69 #if MUTEX == 0
70         decl    (%rdi)
71 #else
72         decl    MUTEX(%rdi)
73 #endif
74         jne     10f
76 11:     addq    $READERS_WAKEUP, %rdi
77 #if FUTEX_WAIT == 0
78         xorl    %esi, %esi
79 #else
80         movl    $FUTEX_WAIT, %esi
81 #endif
82         movl    $SYS_futex, %eax
83         syscall
85         subq    $READERS_WAKEUP, %rdi
87         /* Reget the lock.  */
88         movl    $1, %esi
89         xorl    %eax, %eax
90         LOCK
91 #if MUTEX == 0
92         cmpxchgl %esi, (%rdi)
93 #else
94         cmpxchgl %esi, MUTEX(%rdi)
95 #endif
96         jnz     12f
98 13:     decl    READERS_QUEUED(%rdi)
99         jmp     2b
101 5:      xorl    %edx, %edx
102         incl    NR_READERS(%rdi)
103         je      8f
104 9:      LOCK
105 #if MUTEX == 0
106         decl    (%rdi)
107 #else
108         decl    MUTEX(%rdi)
109 #endif
110         jne     6f
113         movq    %rdx, %rax
114         retq
117 #if MUTEX != 0
118         addq    $MUTEX, %rdi
119 #endif
120         callq   __lll_mutex_lock_wait
121 #if MUTEX != 0
122         subq    $MUTEX, %rdi
123 #endif
124         jmp     2b
126 14:     cmpl    %fs:TID, %eax
127         jne     3b
128         /* Deadlock detected.  */
129         movl    $EDEADLK, %edx
130         jmp     9b
133 #if MUTEX != 0
134         addq    $MUTEX, %rdi
135 #endif
136         callq   __lll_mutex_unlock_wake
137 #if MUTEX != 0
138         subq    $MUTEX, %rdi
139 #endif
140         jmp     7b
142         /* Overflow.  */
143 8:      decl    NR_READERS(%rdi)
144         movl    $EAGAIN, %edx
145         jmp     9b
147         /* Overflow.  */
148 4:      decl    READERS_QUEUED(%rdi)
149         movl    $EAGAIN, %edx
150         jmp     9b
153 #if MUTEX != 0
154         addq    $MUTEX, %rdi
155 #endif
156         callq   __lll_mutex_unlock_wake
157 #if MUTEX != 0
158         subq    $MUTEX, %rdi
159 #endif
160         jmp     11b
163 #if MUTEX == 0
164         addq    $MUTEX, %rdi
165 #endif
166         callq   __lll_mutex_lock_wait
167 #if MUTEX != 0
168         subq    $MUTEX, %rdi
169 #endif
170         jmp     13b
171         .size   __pthread_rwlock_rdlock,.-__pthread_rwlock_rdlock
173         .globl  pthread_rwlock_rdlock
174 pthread_rwlock_rdlock = __pthread_rwlock_rdlock
176         .globl  __pthread_rwlock_rdlock_internal
177 __pthread_rwlock_rdlock_internal = __pthread_rwlock_rdlock