2.5-18.1
[glibc.git] / nptl / sysdeps / unix / sysv / linux / i386 / i486 / pthread_rwlock_rdlock.S
blobdb0639d21c5f4682b60ce0b975e643cea5b708be
1 /* Copyright (C) 2002, 2003 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               240
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         pushl   %esi
43         pushl   %ebx
45         xorl    %esi, %esi
46         movl    12(%esp), %ebx
48         /* Get the lock.  */
49         movl    $1, %edx
50         xorl    %eax, %eax
51         LOCK
52 #if MUTEX == 0
53         cmpxchgl %edx, (%ebx)
54 #else
55         cmpxchgl %edx, MUTEX(%ebx)
56 #endif
57         jnz     1f
59 2:      movl    WRITER(%ebx), %eax
60         testl   %eax, %eax
61         jne     14f
62         cmpl    $0, WRITERS_QUEUED(%ebx)
63         je      5f
64         cmpl    $0, FLAGS(%ebx)
65         je      5f
67 3:      addl    $1, READERS_QUEUED(%ebx)
68         je      4f
70         movl    READERS_WAKEUP(%ebx), %edx
72         LOCK
73 #if MUTEX == 0
74         subl    $1, (%ebx)
75 #else
76         subl    $1, MUTEX(%ebx)
77 #endif
78         jne     10f
80 11:     addl    $READERS_WAKEUP, %ebx
81         movl    %esi, %ecx      /* movl $FUTEX_WAIT, %ecx */
82         movl    $SYS_futex, %eax
83         ENTER_KERNEL
85         subl    $READERS_WAKEUP, %ebx
87         /* Reget the lock.  */
88         movl    $1, %edx
89         xorl    %eax, %eax
90         LOCK
91 #if MUTEX == 0
92         cmpxchgl %edx, (%ebx)
93 #else
94         cmpxchgl %edx, MUTEX(%ebx)
95 #endif
96         jnz     12f
98 13:     subl    $1, READERS_QUEUED(%ebx)
99         jmp     2b
101 5:      xorl    %ecx, %ecx
102         addl    $1, NR_READERS(%ebx)
103         je      8f
104 9:      LOCK
105 #if MUTEX == 0
106         subl    $1, (%ebx)
107 #else
108         subl    $1, MUTEX(%ebx)
109 #endif
110         jne     6f
113         movl    %ecx, %eax
114         popl    %ebx
115         popl    %esi
116         ret
119 #if MUTEX == 0
120         movl    %ebx, %ecx
121 #else
122         leal    MUTEX(%ebx), %ecx
123 #endif
124         call    __lll_mutex_lock_wait
125         jmp     2b
127 14:     cmpl    %gs:TID, %eax
128         jne     3b
129         /* Deadlock detected.  */
130         movl    $EDEADLK, %ecx
131         jmp     9b
134 #if MUTEX == 0
135         movl    %ebx, %eax
136 #else
137         leal    MUTEX(%ebx), %eax
138 #endif
139         call    __lll_mutex_unlock_wake
140         jmp     7b
142         /* Overflow.  */
143 8:      subl    $1, NR_READERS(%ebx)
144         movl    $EAGAIN, %ecx
145         jmp     9b
147         /* Overflow.  */
148 4:      subl    $1, READERS_QUEUED(%ebx)
149         movl    $EAGAIN, %ecx
150         jmp     9b
153 #if MUTEX == 0
154         movl    %ebx, %eax
155 #else
156         leal    MUTEX(%ebx), %eax
157 #endif
158         call    __lll_mutex_unlock_wake
159         jmp     11b
162 #if MUTEX == 0
163         movl    %ebx, %ecx
164 #else
165         leal    MUTEX(%ebx), %ecx
166 #endif
167         call    __lll_mutex_lock_wait
168         jmp     13b
169         .size   __pthread_rwlock_rdlock,.-__pthread_rwlock_rdlock
171         .globl  pthread_rwlock_rdlock
172 pthread_rwlock_rdlock = __pthread_rwlock_rdlock
174         .globl  __pthread_rwlock_rdlock_internal
175 __pthread_rwlock_rdlock_internal = __pthread_rwlock_rdlock