Update copyright notices with scripts/update-copyrights
[glibc.git] / nptl / sysdeps / unix / sysv / linux / i386 / i486 / pthread_rwlock_timedwrlock.S
blob9abba58ca8cba5cf60519d082b38e363e153c074
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_timedwrlock
29         .type   pthread_rwlock_timedwrlock,@function
30         .align  16
31 pthread_rwlock_timedwrlock:
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, NR_READERS(%ebp)
66         je      5f
68         /* Check the value of the timeout parameter.  */
69 3:      cmpl    $1000000000, 4(%edi)
70         jae     19f
72         addl    $1, WRITERS_QUEUED(%ebp)
73         je      4f
75         movl    WRITERS_WAKEUP(%ebp), %esi
77         LOCK
78 #if MUTEX == 0
79         subl    $1, (%ebp)
80 #else
81         subl    $1, MUTEX(%ebp)
82 #endif
83         jne     10f
85         /* Get current time.  */
86 11:     movl    %esp, %ebx
87         xorl    %ecx, %ecx
88         movl    $__NR_gettimeofday, %eax
89         ENTER_KERNEL
91         /* Compute relative timeout.  */
92         movl    4(%esp), %eax
93         movl    $1000, %edx
94         mul     %edx            /* Milli seconds to nano seconds.  */
95         movl    (%edi), %ecx
96         movl    4(%edi), %edx
97         subl    (%esp), %ecx
98         subl    %eax, %edx
99         jns     15f
100         addl    $1000000000, %edx
101         subl    $1, %ecx
102 15:     testl   %ecx, %ecx
103         js      16f             /* Time is already up.  */
105         /* Futex call.  */
106         movl    %ecx, (%esp)    /* Store relative timeout.  */
107         movl    %edx, 4(%esp)
109         movl    %esi, %edx
110 #ifdef __ASSUME_PRIVATE_FUTEX
111         movzbl  PSHARED(%ebp), %ecx
112         xorl    $FUTEX_PRIVATE_FLAG|FUTEX_WAIT, %ecx
113 #else
114         movzbl  PSHARED(%ebp), %ecx
115 # if FUTEX_WAIT != 0
116         orl     $FUTEX_WAIT, %ecx
117 # endif
118         xorl    %gs:PRIVATE_FUTEX, %ecx
119 #endif
120         movl    %esp, %esi
121         leal    WRITERS_WAKEUP(%ebp), %ebx
122         movl    $SYS_futex, %eax
123         ENTER_KERNEL
124         movl    %eax, %esi
127         /* Reget the lock.  */
128         movl    $1, %edx
129         xorl    %eax, %eax
130         LOCK
131 #if MUTEX == 0
132         cmpxchgl %edx, (%ebp)
133 #else
134         cmpxchgl %edx, MUTEX(%ebp)
135 #endif
136         jnz     12f
138 13:     subl    $1, WRITERS_QUEUED(%ebp)
139         cmpl    $-ETIMEDOUT, %esi
140         jne     2b
142 18:     movl    $ETIMEDOUT, %edx
143         jmp     9f
146 5:      xorl    %edx, %edx
147         movl    %gs:TID, %eax
148         movl    %eax, WRITER(%ebp)
149 9:      LOCK
150 #if MUTEX == 0
151         subl    $1, (%ebp)
152 #else
153         subl    $1, MUTEX(%ebp)
154 #endif
155         jne     6f
157 7:      movl    %edx, %eax
159         addl    $8, %esp
160         cfi_adjust_cfa_offset(-8)
161         popl    %ebp
162         cfi_adjust_cfa_offset(-4)
163         cfi_restore(%ebp)
164         popl    %ebx
165         cfi_adjust_cfa_offset(-4)
166         cfi_restore(%ebx)
167         popl    %edi
168         cfi_adjust_cfa_offset(-4)
169         cfi_restore(%edi)
170         popl    %esi
171         cfi_adjust_cfa_offset(-4)
172         cfi_restore(%esi)
173         ret
175         cfi_adjust_cfa_offset(24)
176         cfi_offset(%esi, -8)
177         cfi_offset(%edi, -12)
178         cfi_offset(%ebx, -16)
179         cfi_offset(%ebp, -20)
181 #if MUTEX == 0
182         movl    %ebp, %edx
183 #else
184         leal    MUTEX(%ebp), %edx
185 #endif
186         movzbl  PSHARED(%ebp), %ecx
187         call    __lll_lock_wait
188         jmp     2b
190 14:     cmpl    %gs:TID, %eax
191         jne     3b
192 20:     movl    $EDEADLK, %edx
193         jmp     9b
196 #if MUTEX == 0
197         movl    %ebp, %eax
198 #else
199         leal    MUTEX(%ebp), %eax
200 #endif
201         movzbl  PSHARED(%ebp), %ecx
202         call    __lll_unlock_wake
203         jmp     7b
205         /* Overflow.  */
206 4:      subl    $1, WRITERS_QUEUED(%ebp)
207         movl    $EAGAIN, %edx
208         jmp     9b
211 #if MUTEX == 0
212         movl    %ebp, %eax
213 #else
214         leal    MUTEX(%ebp), %eax
215 #endif
216         movzbl  PSHARED(%ebp), %ecx
217         call    __lll_unlock_wake
218         jmp     11b
221 #if MUTEX == 0
222         movl    %ebp, %edx
223 #else
224         leal    MUTEX(%ebp), %edx
225 #endif
226         movzbl  PSHARED(%ebp), %ecx
227         call    __lll_lock_wait
228         jmp     13b
230 16:     movl    $-ETIMEDOUT, %esi
231         jmp     17b
233 19:     movl    $EINVAL, %edx
234         jmp     9b
235         cfi_endproc
236         .size   pthread_rwlock_timedwrlock,.-pthread_rwlock_timedwrlock