Update copyright notices with scripts/update-copyrights
[glibc.git] / nptl / sysdeps / unix / sysv / linux / i386 / i486 / pthread_rwlock_timedrdlock.S
blobbc1001ce9c59c21bf8d0747cd7f7f370fbb5396c
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>
26         .text
28         .globl  pthread_rwlock_timedrdlock
29         .type   pthread_rwlock_timedrdlock,@function
30         .align  16
31 pthread_rwlock_timedrdlock:
32         cfi_startproc
33         pushl   %esi
34         cfi_adjust_cfa_offset(4)
35         pushl   %edi
36         cfi_adjust_cfa_offset(4)
37         pushl   %ebx
38         cfi_adjust_cfa_offset(4)
39         pushl   %ebp
40         cfi_adjust_cfa_offset(4)
41         cfi_offset(%esi, -8)
42         cfi_offset(%edi, -12)
43         cfi_offset(%ebx, -16)
44         cfi_offset(%ebp, -20)
45         subl    $8, %esp
46         cfi_adjust_cfa_offset(8)
48         movl    28(%esp), %ebp
49         movl    32(%esp), %edi
51         /* Get the lock.  */
52         movl    $1, %edx
53         xorl    %eax, %eax
54         LOCK
55 #if MUTEX == 0
56         cmpxchgl %edx, (%ebp)
57 #else
58         cmpxchgl %edx, MUTEX(%ebp)
59 #endif
60         jnz     1f
62 2:      movl    WRITER(%ebp), %eax
63         testl   %eax, %eax
64         jne     14f
65         cmpl    $0, WRITERS_QUEUED(%ebp)
66         je      5f
67         cmpb    $0, FLAGS(%ebp)
68         je      5f
70         /* Check the value of the timeout parameter.  */
71 3:      cmpl    $1000000000, 4(%edi)
72         jae     19f
74         addl    $1, READERS_QUEUED(%ebp)
75         je      4f
77         movl    READERS_WAKEUP(%ebp), %esi
79         LOCK
80 #if MUTEX == 0
81         subl    $1, (%ebp)
82 #else
83         subl    $1, MUTEX(%ebp)
84 #endif
85         jne     10f
87         /* Get current time.  */
88 11:     movl    %esp, %ebx
89         xorl    %ecx, %ecx
90         movl    $__NR_gettimeofday, %eax
91         ENTER_KERNEL
93         /* Compute relative timeout.  */
94         movl    4(%esp), %eax
95         movl    $1000, %edx
96         mul     %edx            /* Milli seconds to nano seconds.  */
97         movl    (%edi), %ecx
98         movl    4(%edi), %edx
99         subl    (%esp), %ecx
100         subl    %eax, %edx
101         jns     15f
102         addl    $1000000000, %edx
103         subl    $1, %ecx
104 15:     testl   %ecx, %ecx
105         js      16f             /* Time is already up.  */
107         /* Futex call.  */
108         movl    %ecx, (%esp)    /* Store relative timeout.  */
109         movl    %edx, 4(%esp)
111         movl    %esi, %edx
112 #ifdef __ASSUME_PRIVATE_FUTEX
113         movzbl  PSHARED(%ebp), %ecx
114         xorl    $FUTEX_PRIVATE_FLAG|FUTEX_WAIT, %ecx
115 #else
116         movzbl  PSHARED(%ebp), %ecx
117 # if FUTEX_WAIT != 0
118         orl     $FUTEX_WAIT, %ecx
119 # endif
120         xorl    %gs:PRIVATE_FUTEX, %ecx
121 #endif
122         movl    %esp, %esi
123         leal    READERS_WAKEUP(%ebp), %ebx
124         movl    $SYS_futex, %eax
125         ENTER_KERNEL
126         movl    %eax, %esi
129         /* Reget the lock.  */
130         movl    $1, %edx
131         xorl    %eax, %eax
132         LOCK
133 #if MUTEX == 0
134         cmpxchgl %edx, (%ebp)
135 #else
136         cmpxchgl %edx, MUTEX(%ebp)
137 #endif
138         jnz     12f
140 13:     subl    $1, READERS_QUEUED(%ebp)
141         cmpl    $-ETIMEDOUT, %esi
142         jne     2b
144 18:     movl    $ETIMEDOUT, %edx
145         jmp     9f
148 5:      xorl    %edx, %edx
149         addl    $1, NR_READERS(%ebp)
150         je      8f
151 9:      LOCK
152 #if MUTEX == 0
153         subl    $1, (%ebp)
154 #else
155         subl    $1, MUTEX(%ebp)
156 #endif
157         jne     6f
159 7:      movl    %edx, %eax
161         addl    $8, %esp
162         cfi_adjust_cfa_offset(-8)
163         popl    %ebp
164         cfi_adjust_cfa_offset(-4)
165         cfi_restore(%ebp)
166         popl    %ebx
167         cfi_adjust_cfa_offset(-4)
168         cfi_restore(%ebx)
169         popl    %edi
170         cfi_adjust_cfa_offset(-4)
171         cfi_restore(%edi)
172         popl    %esi
173         cfi_adjust_cfa_offset(-4)
174         cfi_restore(%esi)
175         ret
177         cfi_adjust_cfa_offset(24)
178         cfi_offset(%esi, -8)
179         cfi_offset(%edi, -12)
180         cfi_offset(%ebx, -16)
181         cfi_offset(%ebp, -20)
183 #if MUTEX == 0
184         movl    %ebp, %edx
185 #else
186         leal    MUTEX(%ebp), %edx
187 #endif
188         movzbl  PSHARED(%ebp), %ecx
189         call    __lll_lock_wait
190         jmp     2b
192 14:     cmpl    %gs:TID, %eax
193         jne     3b
194         movl    $EDEADLK, %edx
195         jmp     9b
198 #if MUTEX == 0
199         movl    %ebp, %eax
200 #else
201         leal    MUTEX(%ebp), %eax
202 #endif
203         movzbl  PSHARED(%ebp), %ecx
204         call    __lll_unlock_wake
205         jmp     7b
207         /* Overflow.  */
208 8:      subl    $1, NR_READERS(%ebp)
209         movl    $EAGAIN, %edx
210         jmp     9b
212         /* Overflow.  */
213 4:      subl    $1, READERS_QUEUED(%ebp)
214         movl    $EAGAIN, %edx
215         jmp     9b
218 #if MUTEX == 0
219         movl    %ebp, %eax
220 #else
221         leal    MUTEX(%ebp), %eax
222 #endif
223         movzbl  PSHARED(%ebp), %ecx
224         call    __lll_unlock_wake
225         jmp     11b
228 #if MUTEX == 0
229         movl    %ebp, %edx
230 #else
231         leal    MUTEX(%ebp), %edx
232 #endif
233         movzbl  PSHARED(%ebp), %ecx
234         call    __lll_lock_wait
235         jmp     13b
237 16:     movl    $-ETIMEDOUT, %esi
238         jmp     17b
240 19:     movl    $EINVAL, %edx
241         jmp     9b
242         cfi_endproc
243         .size   pthread_rwlock_timedrdlock,.-pthread_rwlock_timedrdlock