]> sourceware.org Git - glibc.git/blob - nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S
Update.
[glibc.git] / nptl / sysdeps / unix / sysv / linux / i386 / i486 / pthread_cond_wait.S
1 /* Copyright (C) 2002, 2003 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 <shlib-compat.h>
22 #include <lowlevelcond.h>
23 #include <tcb-offsets.h>
24
25 #ifdef UP
26 # define LOCK
27 #else
28 # define LOCK lock
29 #endif
30
31 #define SYS_futex 240
32 #define FUTEX_WAIT 0
33 #define FUTEX_WAKE 1
34
35
36 .text
37
38 .align 16
39 .type __condvar_cleanup, @function
40 .globl __condvar_cleanup
41 .hidden __condvar_cleanup
42 __condvar_cleanup:
43 pushl %ebx
44 pushl %esi
45 movl 12(%esp), %esi
46
47 /* Get internal lock. */
48 movl 4(%esi), %ebx
49 movl $1, %eax
50 LOCK
51 #if cond_lock == 0
52 xaddl %eax, (%ebx)
53 #else
54 xaddl %eax, cond_lock(%ebx)
55 #endif
56 testl %eax, %eax
57 je 1f
58
59 #if cond_lock == 0
60 movl %ebx, %ecx
61 #else
62 leal cond_lock(%ebx), %ecx
63 #endif
64 call __lll_mutex_lock_wait
65
66 1: addl $wakeup_seq, %ebx
67 addl $1, (%ebx)
68 adcl $0, 4(%ebx)
69
70 addl $1, woken_seq-wakeup_seq(%ebx)
71 adcl $0, woken_seq-wakeup_seq+4(%ebx)
72
73 LOCK
74 subl $1, cond_lock-wakeup_seq(%ebx)
75 je 2f
76
77 leal cond_lock-wakeup_seq(%ebx), %eax
78 call __lll_mutex_unlock_wake
79
80 /* Wake up all waiters to make sure no signal gets lost. */
81 2: movl $FUTEX_WAKE, %ecx
82 movl $SYS_futex, %eax
83 movl $0x7fffffff, %edx
84 ENTER_KERNEL
85
86 /* Lock the mutex unless asynchronous cancellation is in effect. */
87 testl $2, 8(%esi)
88 jne 3f
89
90 pushl (%esi)
91 call __pthread_mutex_lock_internal
92 popl %eax
93
94 3: popl %esi
95 popl %ebx
96 ret
97 .size __condvar_cleanup, .-__condvar_cleanup
98
99
100 /* int pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex) */
101 .globl __pthread_cond_wait
102 .type __pthread_cond_wait, @function
103 .align 16
104 __pthread_cond_wait:
105 .LSTARTCODE:
106
107 pushl %edi
108 .Lpush_edi:
109 pushl %esi
110 .Lpush_esi:
111 pushl %ebx
112 .Lpush_ebx:
113
114 xorl %esi, %esi
115 movl 16(%esp), %ebx
116
117 /* Get internal lock. */
118 movl $1, %eax
119 LOCK
120 #if cond_lock == 0
121 xaddl %eax, (%ebx)
122 #else
123 xaddl %eax, cond_lock(%ebx)
124 #endif
125 testl %eax, %eax
126 jne 1f
127
128 /* Unlock the mutex. */
129 2: pushl 20(%esp)
130 .Lpush4:
131 call __pthread_mutex_unlock_internal
132
133 testl %eax, %eax
134 jne 12f
135
136 addl $1, total_seq(%ebx)
137 adcl $0, total_seq+4(%ebx)
138
139 /* Install cancellation handler. */
140 #ifdef PIC
141 call __i686.get_pc_thunk.cx
142 addl $_GLOBAL_OFFSET_TABLE_, %ecx
143 leal __condvar_cleanup@GOTOFF(%ecx), %eax
144 #else
145 leal __condvar_cleanup, %eax
146 #endif
147 subl $32, %esp
148 .Lsubl:
149 leal 20(%esp), %edx
150 movl %esp, 8(%esp)
151 movl %eax, 4(%esp)
152 movl %edx, (%esp)
153 call __pthread_cleanup_push
154
155 /* Get and store current wakeup_seq value. */
156 movl 56(%esp), %ecx
157 movl wakeup_seq(%ebx), %edi
158 movl wakeup_seq+4(%ebx), %edx
159 movl %edi, 12(%esp)
160 movl %edx, 16(%esp)
161 /* Prepare structure passed to cancellation handler. */
162 movl %ecx, (%esp)
163 movl %ebx, 4(%esp)
164
165 /* Unlock. */
166 8: LOCK
167 #if cond_lock == 0
168 subl $1, (%ebx)
169 #else
170 subl $1, cond_lock(%ebx)
171 #endif
172 jne 3f
173
174 4: leal 8(%esp), %eax
175 call __pthread_enable_asynccancel_2
176
177 movl %esi, %ecx /* movl $FUTEX_WAIT, %ecx */
178 movl %edi, %edx
179 addl $wakeup_seq, %ebx
180 movl $SYS_futex, %eax
181 ENTER_KERNEL
182 subl $wakeup_seq, %ebx
183
184 movl 8(%esp), %eax
185 call __pthread_disable_asynccancel
186
187 /* Lock. */
188 movl $1, %eax
189 LOCK
190 #if cond_lock == 0
191 xaddl %eax, (%ebx)
192 #else
193 xaddl %eax, cond_lock(%ebx)
194 #endif
195 testl %eax, %eax
196 jne 5f
197
198 6: movl woken_seq(%ebx), %eax
199 movl woken_seq+4(%ebx), %ecx
200
201 movl wakeup_seq(%ebx), %edi
202 movl wakeup_seq+4(%ebx), %edx
203
204 cmpl 16(%esp), %edx
205 ja 7f
206 jb 8b
207 cmpl 12(%esp), %edi
208 jbe 8b
209
210 7: cmpl %ecx, %edx
211 ja 9f
212 jb 8b
213 cmp %eax, %edi
214 jna 8b
215
216 9: addl $1, woken_seq(%ebx)
217 adcl $0, woken_seq+4(%ebx)
218
219 LOCK
220 #if cond_lock == 0
221 subl $1, (%ebx)
222 #else
223 subl $1, cond_lock(%ebx)
224 #endif
225 jne 10f
226
227 /* Remove cancellation handler. */
228 11: movl 20+CLEANUP_PREV(%esp), %edx
229 movl %edx, %gs:CLEANUP
230
231 /* Trick ahead: (%esp) contains the address of the mutex. */
232 call __pthread_mutex_lock_internal
233 addl $36, %esp
234 .Laddl:
235
236 14: popl %ebx
237 .Lpop_ebx:
238 popl %esi
239 .Lpop_esi:
240 popl %edi
241 .Lpop_edi:
242
243 /* We return the result of the mutex_lock operation. */
244 ret
245
246 /* Initial locking failed. */
247 1:
248 .LSbl1:
249 #if cond_lock == 0
250 movl %ebx, %ecx
251 #else
252 leal cond_lock(%ebx), %ecx
253 #endif
254 call __lll_mutex_lock_wait
255 jmp 2b
256
257 /* Unlock in loop requires waekup. */
258 3:
259 .LSbl2:
260 #if cond_lock == 0
261 movl %ebx, %eax
262 #else
263 leal cond_lock(%ebx), %eax
264 #endif
265 call __lll_mutex_unlock_wake
266 jmp 4b
267
268 /* Locking in loop failed. */
269 5:
270 #if cond_lock == 0
271 movl %ebx, %ecx
272 #else
273 leal cond_lock(%ebx), %ecx
274 #endif
275 call __lll_mutex_lock_wait
276 jmp 6b
277
278 /* Unlock after loop requires wakeup. */
279 10:
280 #if cond_lock == 0
281 movl %ebx, %eax
282 #else
283 leal cond_lock(%ebx), %eax
284 #endif
285 call __lll_mutex_unlock_wake
286 jmp 11b
287
288 /* The initial unlocking of the mutex failed. */
289 12:
290 .LSbl3:
291 movl %eax, (%esp)
292 LOCK
293 #if cond_lock == 0
294 subl $1, (%ebx)
295 #else
296 subl $1, cond_lock(%ebx)
297 #endif
298 jne 13f
299
300 #if cond_lock == 0
301 movl %ebx, %eax
302 #else
303 leal cond_lock(%ebx), %eax
304 #endif
305 call __lll_mutex_unlock_wake
306
307 13: popl %eax
308 jmp 14b
309 .LENDCODE:
310 .size __pthread_cond_wait, .-__pthread_cond_wait
311 versioned_symbol (libpthread, __pthread_cond_wait, pthread_cond_wait,
312 GLIBC_2_3_2)
313
314
315 .section .eh_frame,"a",@progbits
316 .LSTARTFRAME:
317 .long L(ENDCIE)-L(STARTCIE) # Length of the CIE.
318 .LSTARTCIE:
319 .long 0 # CIE ID.
320 .byte 1 # Version number.
321 #ifdef SHARED
322 .string "zR" # NUL-terminated augmentation string.
323 #else
324 .ascii "\0" # NUL-terminated augmentation string.
325 #endif
326 .uleb128 1 # Code alignment factor.
327 .sleb128 -4 # Data alignment factor.
328 .byte 8 # Return address register column.
329 #ifdef SHARED
330 .uleb128 1 # Augmentation value length.
331 .byte 0x1b # Encoding: DW_EH_PE_pcrel
332 # + DW_EH_PE_sdata4.
333 #endif
334 .byte 0x0c # DW_CFA_def_cfa
335 .uleb128 4
336 .uleb128 4
337 .byte 0x88 # DW_CFA_offset, column 0x8
338 .uleb128 1
339 .align 4
340 .LENDCIE:
341
342 .long .LENDFDE-.LSTARTFDE # Length of the FDE.
343 .LSTARTFDE:
344 .long .LSTARTFDE-.LSTARTFRAME # CIE pointer.
345 #ifdef SHARED
346 .long .LSTARTCODE-. # PC-relative start address of the code
347 #else
348 .long .LSTARTCODE # Start address of the code.
349 #endif
350 .long .LENDCODE-.LSTARTCODE # Length of the code.
351 #ifdef SHARED
352 .uleb128 0 # No augmentation data.
353 #endif
354 .byte 4 # DW_CFA_advance_loc4
355 .long .Lpush_edi-.LSTARTCODE
356 .byte 14 # DW_CFA_def_cfa_offset
357 .uleb128 8
358 .byte 4 # DW_CFA_advance_loc4
359 .long .Lpush_esi-.Lpush_edi
360 .byte 14 # DW_CFA_def_cfa_offset
361 .uleb128 12
362 .byte 4 # DW_CFA_advance_loc4
363 .long .Lpush_ebx-.Lpush_esi
364 .byte 14 # DW_CFA_def_cfa_offset
365 .uleb128 16
366 .byte 4 # DW_CFA_advance_loc4
367 .long .Lpush4-.Lpush_ebx
368 .byte 14 # DW_CFA_def_cfa_offset
369 .uleb128 20
370 .byte 4 # DW_CFA_advance_loc4
371 .long .Lsubl-.Lpush4
372 .byte 14 # DW_CFA_def_cfa_offset
373 .uleb128 52
374 .byte 4 # DW_CFA_advance_loc4
375 .long .Laddl-.Lsubl
376 .byte 14 # DW_CFA_def_cfa_offset
377 .uleb128 16
378 .byte 4 # DW_CFA_advance_loc4
379 .long .Lpop_ebx-.Laddl
380 .byte 14 # DW_CFA_def_cfa_offset
381 .uleb128 12
382 .byte 4 # DW_CFA_advance_loc4
383 .long .Lpop_esi-.Lpop_ebx
384 .byte 14 # DW_CFA_def_cfa_offset
385 .uleb128 8
386 .byte 4 # DW_CFA_advance_loc4
387 .long .Lpop_edi-.Lpop_esi
388 .byte 14 # DW_CFA_def_cfa_offset
389 .uleb128 4
390 .byte 4 # DW_CFA_advance_loc4
391 .long .LSbl1-.Lpop_edi
392 .byte 14 # DW_CFA_def_cfa_offset
393 .uleb128 16
394 .byte 4 # DW_CFA_advance_loc4
395 .long .LSbl2-.LSbl1
396 .byte 14 # DW_CFA_def_cfa_offset
397 .uleb128 52
398 .byte 4 # DW_CFA_advance_loc4
399 .long .LSbl3-.LSbl2
400 .byte 14 # DW_CFA_def_cfa_offset
401 .uleb128 20
402 .align 4
403 .LENDFDE:
404
405
406 #ifdef PIC
407 .section .gnu.linkonce.t.__i686.get_pc_thunk.cx,"ax",@progbits
408 .globl __i686.get_pc_thunk.cx
409 .hidden __i686.get_pc_thunk.cx
410 .type __i686.get_pc_thunk.cx,@function
411 __i686.get_pc_thunk.cx:
412 movl (%esp), %ecx;
413 ret
414 .size __i686.get_pc_thunk.cx,.-__i686.get_pc_thunk.cx
415 #endif
This page took 0.054871 seconds and 5 git commands to generate.