]> git.ipfire.org Git - thirdparty/glibc.git/blame - nptl/sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S
(CFLAGS-tst-align.c): Add -mpreferred-stack-boundary=4.
[thirdparty/glibc.git] / nptl / sysdeps / unix / sysv / linux / i386 / i486 / sem_timedwait.S
CommitLineData
a334319f 1/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
1d087a7e
UD
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>
326132db 22#include <pthread-errnos.h>
1d087a7e
UD
23
24#ifndef UP
25# define LOCK lock
26#else
27# define
28#endif
29
30#define SYS_gettimeofday __NR_gettimeofday
31#define SYS_futex 240
32#define FUTEX_WAKE 1
33
1d087a7e
UD
34
35 .text
36
37 .globl sem_timedwait
38 .type sem_timedwait,@function
39 .align 16
7726edc2 40 cfi_startproc
1d087a7e 41sem_timedwait:
7726edc2
UD
42 /* First check for cancellation. */
43 movl %gs:CANCELHANDLING, %eax
44 andl $0xfffffff9, %eax
45 cmpl $8, %eax
46 je 10f
47
1d087a7e
UD
48 movl 4(%esp), %ecx
49
50 movl (%ecx), %eax
512: testl %eax, %eax
a334319f 52 je,pn 1f
1d087a7e
UD
53
54 leal -1(%eax), %edx
55 LOCK
56 cmpxchgl %edx, (%ecx)
a334319f 57 jne,pn 2b
1d087a7e
UD
58
59 xorl %eax, %eax
60 ret
61
62 /* Check whether the timeout value is valid. */
631: pushl %esi
7726edc2 64 cfi_adjust_cfa_offset(4)
1d087a7e 65 pushl %edi
7726edc2 66 cfi_adjust_cfa_offset(4)
1d087a7e 67 pushl %ebx
7726edc2
UD
68 cfi_adjust_cfa_offset(4)
69 subl $12, %esp
70 cfi_adjust_cfa_offset(12)
1d087a7e 71
7726edc2
UD
72 movl 32(%esp), %edi
73 cfi_offset(7, -12) /* %edi */
1d087a7e
UD
74
75 /* Check for invalid nanosecond field. */
76 cmpl $1000000000, 4(%edi)
7726edc2
UD
77 movl $EINVAL, %esi
78 cfi_offset(6, -8) /* %esi */
1d087a7e
UD
79 jae 6f
80
7726edc2 81 cfi_offset(3, -16) /* %ebx */
a334319f
UD
827: call __pthread_enable_asynccancel
83 movl %eax, 8(%esp)
84
85 xorl %ecx, %ecx
1d087a7e
UD
86 movl %esp, %ebx
87 movl %ecx, %edx
88 movl $SYS_gettimeofday, %eax
89 ENTER_KERNEL
90
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 5f
100 addl $1000000000, %edx
ccf1d573 101 subl $1, %ecx
1d087a7e 1025: testl %ecx, %ecx
7726edc2 103 movl $ETIMEDOUT, %esi
1d087a7e
UD
104 js 6f /* Time is already up. */
105
106 movl %ecx, (%esp) /* Store relative timeout. */
107 movl %edx, 4(%esp)
7726edc2 108 movl 28(%esp), %ebx
1d087a7e 109 xorl %ecx, %ecx
7726edc2 110 movl %esp, %esi
1d087a7e
UD
111 movl $SYS_futex, %eax
112 xorl %edx, %edx
113 ENTER_KERNEL
7726edc2
UD
114 movl %eax, %esi
115
116 movl 8(%esp), %eax
117 call __pthread_disable_asynccancel
1d087a7e 118
7726edc2 119 testl %esi, %esi
a334319f 120 je,pt 9f
7726edc2 121 cmpl $-EWOULDBLOCK, %esi
1d087a7e
UD
122 jne 3f
123
1249: movl (%ebx), %eax
1258: testl %eax, %eax
126 je 7b
127
128 leal -1(%eax), %ecx
129 LOCK
130 cmpxchgl %ecx, (%ebx)
a334319f 131 jne,pn 8b
1d087a7e 132
7726edc2
UD
133 addl $12, %esp
134 cfi_adjust_cfa_offset(-12)
1d087a7e
UD
135 xorl %eax, %eax
136 popl %ebx
7726edc2
UD
137 cfi_adjust_cfa_offset(-4)
138 cfi_restore(3)
1d087a7e 139 popl %edi
7726edc2
UD
140 cfi_adjust_cfa_offset(-4)
141 cfi_restore(7)
1d087a7e 142 popl %esi
7726edc2
UD
143 cfi_adjust_cfa_offset(-4)
144 cfi_restore(6)
1d087a7e
UD
145 ret
146
7726edc2
UD
147 cfi_adjust_cfa_offset(24)
148 cfi_offset(6, -8) /* %esi */
4123718e 149 cfi_offset(7, -12) /* %edi */
7726edc2
UD
150 cfi_offset(3, -16) /* %ebx */
1513: negl %esi
1d087a7e
UD
1526:
153#ifdef PIC
154 call __i686.get_pc_thunk.bx
155#else
156 movl $4f, %ebx
1574:
158#endif
159 addl $_GLOBAL_OFFSET_TABLE_, %ebx
160#if USE___THREAD
a334319f
UD
161 movl %gs:0, %edx
162 subl errno@gottpoff(%ebx), %edx
7726edc2 163 movl %esi, (%edx)
1d087a7e 164#else
1d087a7e 165 call __errno_location@plt
7726edc2 166 movl %esi, (%eax)
1d087a7e
UD
167#endif
168
7726edc2
UD
169 addl $12, %esp
170 cfi_adjust_cfa_offset(-12)
1d087a7e
UD
171 orl $-1, %eax
172 popl %ebx
7726edc2
UD
173 cfi_adjust_cfa_offset(-4)
174 cfi_restore(3)
1d087a7e 175 popl %edi
7726edc2
UD
176 cfi_adjust_cfa_offset(-4)
177 cfi_restore(7)
1d087a7e 178 popl %esi
7726edc2
UD
179 cfi_adjust_cfa_offset(-4)
180 cfi_restore(6)
1d087a7e 181 ret
7726edc2
UD
182
18310: /* Canceled. */
184 movl $0xffffffff, %gs:RESULT
185 LOCK
186 orl $0x10, %gs:CANCELHANDLING
187 movl %gs:CLEANUP_JMP_BUF, %eax
da0c02ee 188 jmp HIDDEN_JUMPTARGET (__pthread_unwind)
7726edc2 189 cfi_endproc
1d087a7e 190 .size sem_timedwait,.-sem_timedwait