* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S: Access
[glibc.git] / nptl / sysdeps / unix / sysv / linux / i386 / i486 / pthread_rwlock_rdlock.S
blob2ddeed072fcde1414b9221cf07959891bfcfa16b
1 /* Copyright (C) 2002, 2003, 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_rdlock
30         .type   __pthread_rwlock_rdlock,@function
31         .align  16
32 __pthread_rwlock_rdlock:
33         pushl   %esi
34         pushl   %ebx
36         xorl    %esi, %esi
37         movl    12(%esp), %ebx
39         /* Get the lock.  */
40         movl    $1, %edx
41         xorl    %eax, %eax
42         LOCK
43 #if MUTEX == 0
44         cmpxchgl %edx, (%ebx)
45 #else
46         cmpxchgl %edx, MUTEX(%ebx)
47 #endif
48         jnz     1f
50 2:      movl    WRITER(%ebx), %eax
51         testl   %eax, %eax
52         jne     14f
53         cmpl    $0, WRITERS_QUEUED(%ebx)
54         je      5f
55         cmpb    $0, FLAGS(%ebx)
56         je      5f
58 3:      addl    $1, READERS_QUEUED(%ebx)
59         je      4f
61         movl    READERS_WAKEUP(%ebx), %edx
63         LOCK
64 #if MUTEX == 0
65         subl    $1, (%ebx)
66 #else
67         subl    $1, MUTEX(%ebx)
68 #endif
69         jne     10f
71 11:
72 #ifdef __ASSUME_PRIVATE_FUTEX
73         movzbl  PSHARED(%ebx), %ecx
74         xorl    $FUTEX_PRIVATE_FLAG|FUTEX_WAIT, %ecx
75 #else
76         movzbl  PSHARED(%ebx), %ecx
77 # if FUTEX_WAIT != 0
78         orl     $FUTEX_WAIT, %ecx
79 # endif
80         xorl    %gs:PRIVATE_FUTEX, %ecx
81 #endif
82         addl    $READERS_WAKEUP, %ebx
83         movl    $SYS_futex, %eax
84         ENTER_KERNEL
86         subl    $READERS_WAKEUP, %ebx
88         /* Reget the lock.  */
89         movl    $1, %edx
90         xorl    %eax, %eax
91         LOCK
92 #if MUTEX == 0
93         cmpxchgl %edx, (%ebx)
94 #else
95         cmpxchgl %edx, MUTEX(%ebx)
96 #endif
97         jnz     12f
99 13:     subl    $1, READERS_QUEUED(%ebx)
100         jmp     2b
102 5:      xorl    %edx, %edx
103         addl    $1, NR_READERS(%ebx)
104         je      8f
105 9:      LOCK
106 #if MUTEX == 0
107         subl    $1, (%ebx)
108 #else
109         subl    $1, MUTEX(%ebx)
110 #endif
111         jne     6f
114         movl    %edx, %eax
115         popl    %ebx
116         popl    %esi
117         ret
120 #if MUTEX == 0
121         movl    %ebx, %edx
122 #else
123         leal    MUTEX(%ebx), %edx
124 #endif
125         movzbl  PSHARED(%ebx), %ecx
126         call    __lll_lock_wait
127         jmp     2b
129 14:     cmpl    %gs:TID, %eax
130         jne     3b
131         /* Deadlock detected.  */
132         movl    $EDEADLK, %edx
133         jmp     9b
136 #if MUTEX == 0
137         movl    %ebx, %eax
138 #else
139         leal    MUTEX(%ebx), %eax
140 #endif
141         movzbl  PSHARED(%ebx), %ecx
142         call    __lll_unlock_wake
143         jmp     7b
145         /* Overflow.  */
146 8:      subl    $1, NR_READERS(%ebx)
147         movl    $EAGAIN, %edx
148         jmp     9b
150         /* Overflow.  */
151 4:      subl    $1, READERS_QUEUED(%ebx)
152         movl    $EAGAIN, %edx
153         jmp     9b
156 #if MUTEX == 0
157         movl    %ebx, %eax
158 #else
159         leal    MUTEX(%ebx), %eax
160 #endif
161         movzbl  PSHARED(%ebx), %ecx
162         call    __lll_unlock_wake
163         jmp     11b
166 #if MUTEX == 0
167         movl    %ebx, %edx
168 #else
169         leal    MUTEX(%ebx), %edx
170 #endif
171         movzbl  PSHARED(%ebx), %ecx
172         call    __lll_lock_wait
173         jmp     13b
174         .size   __pthread_rwlock_rdlock,.-__pthread_rwlock_rdlock
176         .globl  pthread_rwlock_rdlock
177 pthread_rwlock_rdlock = __pthread_rwlock_rdlock
179         .globl  __pthread_rwlock_rdlock_internal
180 __pthread_rwlock_rdlock_internal = __pthread_rwlock_rdlock