]> sourceware.org Git - glibc.git/blame - 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
CommitLineData
1d087a7e
UD
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>
a7720b5e 23#include <tcb-offsets.h>
1d087a7e
UD
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
a7720b5e
UD
44 pushl %esi
45 movl 12(%esp), %esi
1d087a7e
UD
46
47 /* Get internal lock. */
a7720b5e 48 movl 4(%esi), %ebx
1d087a7e
UD
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
3e976b96
UD
661: addl $wakeup_seq, %ebx
67 addl $1, (%ebx)
68 adcl $0, 4(%ebx)
1d087a7e 69
3e976b96
UD
70 addl $1, woken_seq-wakeup_seq(%ebx)
71 adcl $0, woken_seq-wakeup_seq+4(%ebx)
72
1d087a7e 73 LOCK
3e976b96 74 subl $1, cond_lock-wakeup_seq(%ebx)
1d087a7e 75 je 2f
3e976b96
UD
76
77 leal cond_lock-wakeup_seq(%ebx), %eax
1d087a7e
UD
78 call __lll_mutex_unlock_wake
79
24a49f38
UD
80 /* Wake up all waiters to make sure no signal gets lost. */
812: movl $FUTEX_WAKE, %ecx
82 movl $SYS_futex, %eax
83 movl $0x7fffffff, %edx
84 ENTER_KERNEL
85
816a5a6a 86 /* Lock the mutex unless asynchronous cancellation is in effect. */
ee2af3e8 87 testl $2, 8(%esi)
a7720b5e
UD
88 jne 3f
89
ee2af3e8 90 pushl (%esi)
a7720b5e
UD
91 call __pthread_mutex_lock_internal
92 popl %eax
93
943: popl %esi
95 popl %ebx
1d087a7e
UD
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:
08c765fa 105.LSTARTCODE:
1d087a7e
UD
106
107 pushl %edi
08c765fa 108.Lpush_edi:
1d087a7e 109 pushl %esi
08c765fa 110.Lpush_esi:
1d087a7e 111 pushl %ebx
08c765fa 112.Lpush_ebx:
1d087a7e
UD
113
114 xorl %esi, %esi
115 movl 16(%esp), %ebx
1d087a7e
UD
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. */
1292: pushl 20(%esp)
08c765fa 130.Lpush4:
1d087a7e
UD
131 call __pthread_mutex_unlock_internal
132
a7720b5e
UD
133 testl %eax, %eax
134 jne 12f
135
1d087a7e
UD
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
a7720b5e 147 subl $32, %esp
08c765fa 148.Lsubl:
a7720b5e
UD
149 leal 20(%esp), %edx
150 movl %esp, 8(%esp)
1d087a7e
UD
151 movl %eax, 4(%esp)
152 movl %edx, (%esp)
153 call __pthread_cleanup_push
154
155 /* Get and store current wakeup_seq value. */
a7720b5e 156 movl 56(%esp), %ecx
1d087a7e
UD
157 movl wakeup_seq(%ebx), %edi
158 movl wakeup_seq+4(%ebx), %edx
a7720b5e
UD
159 movl %edi, 12(%esp)
160 movl %edx, 16(%esp)
161 /* Prepare structure passed to cancellation handler. */
ee2af3e8 162 movl %ecx, (%esp)
a7720b5e 163 movl %ebx, 4(%esp)
1d087a7e
UD
164
165 /* Unlock. */
1668: LOCK
167#if cond_lock == 0
ccf1d573 168 subl $1, (%ebx)
1d087a7e 169#else
ccf1d573 170 subl $1, cond_lock(%ebx)
1d087a7e
UD
171#endif
172 jne 3f
173
ee2af3e8 1744: leal 8(%esp), %eax
32a589b1 175 call __pthread_enable_asynccancel_2
1d087a7e
UD
176
177 movl %esi, %ecx /* movl $FUTEX_WAIT, %ecx */
178 movl %edi, %edx
11090a99 179 addl $wakeup_seq, %ebx
1d087a7e
UD
180 movl $SYS_futex, %eax
181 ENTER_KERNEL
11090a99 182 subl $wakeup_seq, %ebx
1d087a7e 183
ee2af3e8 184 movl 8(%esp), %eax
1d087a7e
UD
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
1986: 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
46a32546 204 cmpl 16(%esp), %edx
1d087a7e
UD
205 ja 7f
206 jb 8b
46a32546
UD
207 cmpl 12(%esp), %edi
208 jbe 8b
1d087a7e
UD
209
2107: cmpl %ecx, %edx
211 ja 9f
212 jb 8b
213 cmp %eax, %edi
214 jna 8b
215
2169: addl $1, woken_seq(%ebx)
217 adcl $0, woken_seq+4(%ebx)
218
219 LOCK
220#if cond_lock == 0
ccf1d573 221 subl $1, (%ebx)
1d087a7e 222#else
ccf1d573 223 subl $1, cond_lock(%ebx)
1d087a7e
UD
224#endif
225 jne 10f
226
227 /* Remove cancellation handler. */
748bec08
UD
22811: movl 20+CLEANUP_PREV(%esp), %edx
229 movl %edx, %gs:CLEANUP
1d087a7e 230
ee2af3e8 231 /* Trick ahead: (%esp) contains the address of the mutex. */
1d087a7e 232 call __pthread_mutex_lock_internal
ee2af3e8 233 addl $36, %esp
08c765fa 234.Laddl:
1d087a7e 235
a7720b5e 23614: popl %ebx
08c765fa 237.Lpop_ebx:
1d087a7e 238 popl %esi
08c765fa 239.Lpop_esi:
1d087a7e 240 popl %edi
08c765fa 241.Lpop_edi:
1d087a7e
UD
242
243 /* We return the result of the mutex_lock operation. */
244 ret
245
246 /* Initial locking failed. */
2471:
08c765fa 248.LSbl1:
1d087a7e
UD
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. */
2583:
08c765fa 259.LSbl2:
1d087a7e
UD
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. */
2695:
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
a7720b5e 278 /* Unlock after loop requires wakeup. */
1d087a7e
UD
27910:
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
a7720b5e
UD
287
288 /* The initial unlocking of the mutex failed. */
08c765fa
UD
28912:
290.LSbl3:
291 movl %eax, (%esp)
a7720b5e
UD
292 LOCK
293#if cond_lock == 0
ccf1d573 294 subl $1, (%ebx)
a7720b5e 295#else
ccf1d573 296 subl $1, cond_lock(%ebx)
a7720b5e
UD
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
30713: popl %eax
308 jmp 14b
08c765fa 309.LENDCODE:
1d087a7e
UD
310 .size __pthread_cond_wait, .-__pthread_cond_wait
311versioned_symbol (libpthread, __pthread_cond_wait, pthread_cond_wait,
312 GLIBC_2_3_2)
313
314
08c765fa
UD
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.
ad2be852 351#ifdef SHARED
08c765fa 352 .uleb128 0 # No augmentation data.
ad2be852 353#endif
08c765fa
UD
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
1d087a7e
UD
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.100955 seconds and 5 git commands to generate.