]> git.ipfire.org Git - thirdparty/glibc.git/blob - nptl/sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S
.
[thirdparty/glibc.git] / nptl / sysdeps / unix / sysv / linux / i386 / i486 / sem_timedwait.S
1 /* Copyright (C) 2002, 2003, 2004, 2005, 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 <shlib-compat.h>
22 #include <pthread-errnos.h>
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
34
35 .text
36
37 .globl sem_timedwait
38 .type sem_timedwait,@function
39 .align 16
40 cfi_startproc
41 sem_timedwait:
42 /* First check for cancellation. */
43 movl %gs:CANCELHANDLING, %eax
44 andl $0xfffffff9, %eax
45 cmpl $8, %eax
46 je 10f
47
48 movl 4(%esp), %ecx
49
50 movl (%ecx), %eax
51 2: testl %eax, %eax
52 je 1f
53
54 leal -1(%eax), %edx
55 LOCK
56 cmpxchgl %edx, (%ecx)
57 jne 2b
58
59 xorl %eax, %eax
60 ret
61
62 /* Check whether the timeout value is valid. */
63 1: pushl %esi
64 cfi_adjust_cfa_offset(4)
65 pushl %edi
66 cfi_adjust_cfa_offset(4)
67 pushl %ebx
68 cfi_adjust_cfa_offset(4)
69 subl $12, %esp
70 cfi_adjust_cfa_offset(12)
71
72 movl 32(%esp), %edi
73 cfi_offset(7, -12) /* %edi */
74
75 /* Check for invalid nanosecond field. */
76 cmpl $1000000000, 4(%edi)
77 movl $EINVAL, %esi
78 cfi_offset(6, -8) /* %esi */
79 jae 6f
80
81 cfi_offset(3, -16) /* %ebx */
82 7: xorl %ecx, %ecx
83 movl %esp, %ebx
84 movl %ecx, %edx
85 movl $SYS_gettimeofday, %eax
86 ENTER_KERNEL
87
88 /* Compute relative timeout. */
89 movl 4(%esp), %eax
90 movl $1000, %edx
91 mul %edx /* Milli seconds to nano seconds. */
92 movl (%edi), %ecx
93 movl 4(%edi), %edx
94 subl (%esp), %ecx
95 subl %eax, %edx
96 jns 5f
97 addl $1000000000, %edx
98 subl $1, %ecx
99 5: testl %ecx, %ecx
100 movl $ETIMEDOUT, %esi
101 js 6f /* Time is already up. */
102
103 movl %ecx, (%esp) /* Store relative timeout. */
104 movl %edx, 4(%esp)
105
106 call __pthread_enable_asynccancel
107 movl %eax, 8(%esp)
108
109 movl 28(%esp), %ebx
110 xorl %ecx, %ecx
111 movl %esp, %esi
112 movl $SYS_futex, %eax
113 xorl %edx, %edx
114 ENTER_KERNEL
115 movl %eax, %esi
116
117 movl 8(%esp), %eax
118 call __pthread_disable_asynccancel
119
120 testl %esi, %esi
121 je 9f
122 cmpl $-EWOULDBLOCK, %esi
123 jne 3f
124
125 9: movl (%ebx), %eax
126 8: testl %eax, %eax
127 je 7b
128
129 leal -1(%eax), %ecx
130 LOCK
131 cmpxchgl %ecx, (%ebx)
132 jne 8b
133
134 addl $12, %esp
135 cfi_adjust_cfa_offset(-12)
136 xorl %eax, %eax
137 popl %ebx
138 cfi_adjust_cfa_offset(-4)
139 cfi_restore(3)
140 popl %edi
141 cfi_adjust_cfa_offset(-4)
142 cfi_restore(7)
143 popl %esi
144 cfi_adjust_cfa_offset(-4)
145 cfi_restore(6)
146 ret
147
148 cfi_adjust_cfa_offset(24)
149 cfi_offset(6, -8) /* %esi */
150 cfi_offset(7, -12) /* %edi */
151 cfi_offset(3, -16) /* %ebx */
152 3: negl %esi
153 6:
154 #ifdef PIC
155 call __i686.get_pc_thunk.bx
156 #else
157 movl $4f, %ebx
158 4:
159 #endif
160 addl $_GLOBAL_OFFSET_TABLE_, %ebx
161 #if USE___THREAD
162 # ifdef NO_TLS_DIRECT_SEG_REFS
163 movl errno@gotntpoff(%ebx), %edx
164 addl %gs:0, %edx
165 movl %esi, (%edx)
166 # else
167 movl errno@gotntpoff(%ebx), %edx
168 movl %esi, %gs:(%edx)
169 # endif
170 #else
171 call __errno_location@plt
172 movl %esi, (%eax)
173 #endif
174
175 addl $12, %esp
176 cfi_adjust_cfa_offset(-12)
177 orl $-1, %eax
178 popl %ebx
179 cfi_adjust_cfa_offset(-4)
180 cfi_restore(3)
181 popl %edi
182 cfi_adjust_cfa_offset(-4)
183 cfi_restore(7)
184 popl %esi
185 cfi_adjust_cfa_offset(-4)
186 cfi_restore(6)
187 ret
188
189 10: /* Canceled. */
190 movl $0xffffffff, %gs:RESULT
191 LOCK
192 orl $0x10, %gs:CANCELHANDLING
193 movl %gs:CLEANUP_JMP_BUF, %eax
194 jmp HIDDEN_JUMPTARGET (__pthread_unwind)
195 cfi_endproc
196 .size sem_timedwait,.-sem_timedwait