]>
Commit | Line | Data |
---|---|---|
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 | 41 | sem_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 | |
51 | 2: 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. */ | |
63 | 1: 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 |
82 | 7: 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 | 102 | 5: 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 | ||
124 | 9: movl (%ebx), %eax | |
125 | 8: 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 */ |
151 | 3: negl %esi | |
1d087a7e UD |
152 | 6: |
153 | #ifdef PIC | |
154 | call __i686.get_pc_thunk.bx | |
155 | #else | |
156 | movl $4f, %ebx | |
157 | 4: | |
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 | |
183 | 10: /* 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 |