Update copyright notices with scripts/update-copyrights
[glibc.git] / nptl / sysdeps / unix / sysv / linux / i386 / i486 / pthread_rwlock_rdlock.S
bloba81bc06d7c35d772c5dc96dce110a74942ee3d29
1 /* Copyright (C) 2002-2014 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, see
17    <http://www.gnu.org/licenses/>.  */
19 #include <sysdep.h>
20 #include <lowlevellock.h>
21 #include <lowlevelrwlock.h>
22 #include <pthread-errnos.h>
23 #include <kernel-features.h>
25 #include <stap-probe.h>
27         .text
29         .globl  __pthread_rwlock_rdlock
30         .type   __pthread_rwlock_rdlock,@function
31         .align  16
32 __pthread_rwlock_rdlock:
33         cfi_startproc
34         pushl   %esi
35         cfi_adjust_cfa_offset(4)
36         pushl   %ebx
37         cfi_adjust_cfa_offset(4)
38         cfi_offset(%esi, -8)
39         cfi_offset(%ebx, -12)
41         xorl    %esi, %esi
42         movl    12(%esp), %ebx
44         LIBC_PROBE (rdlock_entry, 1, %ebx)
46         /* Get the lock.  */
47         movl    $1, %edx
48         xorl    %eax, %eax
49         LOCK
50 #if MUTEX == 0
51         cmpxchgl %edx, (%ebx)
52 #else
53         cmpxchgl %edx, MUTEX(%ebx)
54 #endif
55         jnz     1f
57 2:      movl    WRITER(%ebx), %eax
58         testl   %eax, %eax
59         jne     14f
60         cmpl    $0, WRITERS_QUEUED(%ebx)
61         je      5f
62         cmpb    $0, FLAGS(%ebx)
63         je      5f
65 3:      addl    $1, READERS_QUEUED(%ebx)
66         je      4f
68         movl    READERS_WAKEUP(%ebx), %edx
70         LOCK
71 #if MUTEX == 0
72         subl    $1, (%ebx)
73 #else
74         subl    $1, MUTEX(%ebx)
75 #endif
76         jne     10f
78 11:
79 #ifdef __ASSUME_PRIVATE_FUTEX
80         movzbl  PSHARED(%ebx), %ecx
81         xorl    $FUTEX_PRIVATE_FLAG|FUTEX_WAIT, %ecx
82 #else
83         movzbl  PSHARED(%ebx), %ecx
84 # if FUTEX_WAIT != 0
85         orl     $FUTEX_WAIT, %ecx
86 # endif
87         xorl    %gs:PRIVATE_FUTEX, %ecx
88 #endif
89         addl    $READERS_WAKEUP, %ebx
90         movl    $SYS_futex, %eax
91         ENTER_KERNEL
93         subl    $READERS_WAKEUP, %ebx
95         /* Reget the lock.  */
96         movl    $1, %edx
97         xorl    %eax, %eax
98         LOCK
99 #if MUTEX == 0
100         cmpxchgl %edx, (%ebx)
101 #else
102         cmpxchgl %edx, MUTEX(%ebx)
103 #endif
104         jnz     12f
106 13:     subl    $1, READERS_QUEUED(%ebx)
107         jmp     2b
109 5:      xorl    %edx, %edx
110         addl    $1, NR_READERS(%ebx)
111         je      8f
112 9:      LOCK
113 #if MUTEX == 0
114         subl    $1, (%ebx)
115 #else
116         subl    $1, MUTEX(%ebx)
117 #endif
118         jne     6f
121         movl    %edx, %eax
122         popl    %ebx
123         cfi_adjust_cfa_offset(-4)
124         cfi_restore(%ebx)
125         popl    %esi
126         cfi_adjust_cfa_offset(-4)
127         cfi_restore(%esi)
128         ret
130         cfi_adjust_cfa_offset(8)
131         cfi_offset(%esi, -8)
132         cfi_offset(%ebx, -12)
134 #if MUTEX == 0
135         movl    %ebx, %edx
136 #else
137         leal    MUTEX(%ebx), %edx
138 #endif
139         movzbl  PSHARED(%ebx), %ecx
140         call    __lll_lock_wait
141         jmp     2b
143 14:     cmpl    %gs:TID, %eax
144         jne     3b
145         /* Deadlock detected.  */
146         movl    $EDEADLK, %edx
147         jmp     9b
150 #if MUTEX == 0
151         movl    %ebx, %eax
152 #else
153         leal    MUTEX(%ebx), %eax
154 #endif
155         movzbl  PSHARED(%ebx), %ecx
156         call    __lll_unlock_wake
157         jmp     7b
159         /* Overflow.  */
160 8:      subl    $1, NR_READERS(%ebx)
161         movl    $EAGAIN, %edx
162         jmp     9b
164         /* Overflow.  */
165 4:      subl    $1, READERS_QUEUED(%ebx)
166         movl    $EAGAIN, %edx
167         jmp     9b
170 #if MUTEX == 0
171         movl    %ebx, %eax
172 #else
173         leal    MUTEX(%ebx), %eax
174 #endif
175         movzbl  PSHARED(%ebx), %ecx
176         call    __lll_unlock_wake
177         jmp     11b
180 #if MUTEX == 0
181         movl    %ebx, %edx
182 #else
183         leal    MUTEX(%ebx), %edx
184 #endif
185         movzbl  PSHARED(%ebx), %ecx
186         call    __lll_lock_wait
187         jmp     13b
188         cfi_endproc
189         .size   __pthread_rwlock_rdlock,.-__pthread_rwlock_rdlock
191 strong_alias (__pthread_rwlock_rdlock, pthread_rwlock_rdlock)
192 hidden_def (__pthread_rwlock_rdlock)