OSDN Git Service

2013.10.24
[uclinux-h8/uClinux-dist.git] / uClibc / libpthread / nptl / sysdeps / unix / sysv / linux / i386 / i486 / pthread_rwlock_timedwrlock.S
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.
4
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.
9
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.
14
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.  */
19
20 #include <sysdep.h>
21 #include <lowlevellock.h>
22 #include <lowlevelrwlock.h>
23 #include <pthread-errnos.h>
24 #include <bits/kernel-features.h>
25 #include <tls.h>
26
27
28         .text
29
30         .globl  pthread_rwlock_timedwrlock
31         .type   pthread_rwlock_timedwrlock,@function
32         .align  16
33 pthread_rwlock_timedwrlock:
34         cfi_startproc
35         pushl   %esi
36         cfi_adjust_cfa_offset(4)
37         pushl   %edi
38         cfi_adjust_cfa_offset(4)
39         pushl   %ebx
40         cfi_adjust_cfa_offset(4)
41         pushl   %ebp
42         cfi_adjust_cfa_offset(4)
43         cfi_offset(%esi, -8)
44         cfi_offset(%edi, -12)
45         cfi_offset(%ebx, -16)
46         cfi_offset(%ebp, -20)
47         subl    $8, %esp
48         cfi_adjust_cfa_offset(8)
49
50         movl    28(%esp), %ebp
51         movl    32(%esp), %edi
52
53         /* Get the lock.  */
54         movl    $1, %edx
55         xorl    %eax, %eax
56         LOCK
57 #if MUTEX == 0
58         cmpxchgl %edx, (%ebp)
59 #else
60         cmpxchgl %edx, MUTEX(%ebp)
61 #endif
62         jnz     1f
63
64 2:      movl    WRITER(%ebp), %eax
65         testl   %eax, %eax
66         jne     14f
67         cmpl    $0, NR_READERS(%ebp)
68         je      5f
69
70         /* Check the value of the timeout parameter.  */
71 3:      cmpl    $1000000000, 4(%edi)
72         jae     19f
73
74         addl    $1, WRITERS_QUEUED(%ebp)
75         je      4f
76
77         movl    WRITERS_WAKEUP(%ebp), %esi
78
79         LOCK
80 #if MUTEX == 0
81         subl    $1, (%ebp)
82 #else
83         subl    $1, MUTEX(%ebp)
84 #endif
85         jne     10f
86
87         /* Get current time.  */
88 11:     movl    %esp, %ebx
89         xorl    %ecx, %ecx
90         movl    $__NR_gettimeofday, %eax
91         ENTER_KERNEL
92
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.  */
106
107         /* Futex call.  */
108         movl    %ecx, (%esp)    /* Store relative timeout.  */
109         movl    %edx, 4(%esp)
110
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    WRITERS_WAKEUP(%ebp), %ebx
124         movl    $SYS_futex, %eax
125         ENTER_KERNEL
126         movl    %eax, %esi
127 17:
128
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
139
140 13:     subl    $1, WRITERS_QUEUED(%ebp)
141         cmpl    $-ETIMEDOUT, %esi
142         jne     2b
143
144 18:     movl    $ETIMEDOUT, %edx
145         jmp     9f
146
147
148 5:      xorl    %edx, %edx
149         movl    %gs:TID, %eax
150         movl    %eax, WRITER(%ebp)
151 9:      LOCK
152 #if MUTEX == 0
153         subl    $1, (%ebp)
154 #else
155         subl    $1, MUTEX(%ebp)
156 #endif
157         jne     6f
158
159 7:      movl    %edx, %eax
160
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
176
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)
182 1:
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
191
192 14:     cmpl    %gs:TID, %eax
193         jne     3b
194 20:     movl    $EDEADLK, %edx
195         jmp     9b
196
197 6:
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
206
207         /* Overflow.  */
208 4:      subl    $1, WRITERS_QUEUED(%ebp)
209         movl    $EAGAIN, %edx
210         jmp     9b
211
212 10:
213 #if MUTEX == 0
214         movl    %ebp, %eax
215 #else
216         leal    MUTEX(%ebp), %eax
217 #endif
218         movzbl  PSHARED(%ebp), %ecx
219         call    __lll_unlock_wake
220         jmp     11b
221
222 12:
223 #if MUTEX == 0
224         movl    %ebp, %edx
225 #else
226         leal    MUTEX(%ebp), %edx
227 #endif
228         movzbl  PSHARED(%ebp), %ecx
229         call    __lll_lock_wait
230         jmp     13b
231
232 16:     movl    $-ETIMEDOUT, %esi
233         jmp     17b
234
235 19:     movl    $EINVAL, %edx
236         jmp     9b
237         cfi_endproc
238         .size   pthread_rwlock_timedwrlock,.-pthread_rwlock_timedwrlock