]>
Commit | Line | Data |
---|---|---|
d063d164 | 1 | /* Copyright (C) 2003, 2004, 2007, 2011 Free Software Foundation, Inc. |
a54e8d33 UD |
2 | This file is part of the GNU C Library. |
3 | ||
4 | The GNU C Library is free software; you can redistribute it and/or | |
5 | modify it under the terms of the GNU Lesser General Public | |
6 | License as published by the Free Software Foundation; either | |
7 | version 2.1 of the License, or (at your option) any later version. | |
8 | ||
9 | The GNU C Library is distributed in the hope that it will be useful, | |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
12 | Lesser General Public License for more details. | |
13 | ||
14 | You should have received a copy of the GNU Lesser General Public | |
59ba27a6 PE |
15 | License along with the GNU C Library; if not, see |
16 | <http://www.gnu.org/licenses/>. */ | |
a54e8d33 UD |
17 | |
18 | #include <sysdep.h> | |
19 | #include <shlib-compat.h> | |
326132db | 20 | #include <pthread-errnos.h> |
4a17085f | 21 | #include <tcb-offsets.h> |
339dbf0e | 22 | #include <structsem.h> |
ce31a3b1 | 23 | #include <lowlevellock.h> |
a54e8d33 UD |
24 | #include "lowlevel-atomic.h" |
25 | ||
26 | ||
339dbf0e UD |
27 | #if VALUE != 0 |
28 | # error "code needs to be rewritten for VALUE != 0" | |
29 | #endif | |
a54e8d33 | 30 | |
a54e8d33 UD |
31 | .text |
32 | ||
33 | .globl sem_timedwait | |
34 | .type sem_timedwait,@function | |
35 | .align 5 | |
36 | sem_timedwait: | |
339dbf0e | 37 | .LSTARTCODE: |
a54e8d33 UD |
38 | mov.l @r4, r0 |
39 | 2: | |
40 | tst r0, r0 | |
41 | bt 1f | |
42 | mov r0, r3 | |
43 | mov r0, r6 | |
44 | add #-1, r3 | |
45 | CMPXCHG (r6, @r4, r3, r2) | |
46 | bf/s 2b | |
47 | mov r2, r0 | |
48 | rts | |
49 | mov #0, r0 | |
50 | ||
51 | 1: | |
52 | /* Check whether the timeout value is valid. */ | |
a54e8d33 | 53 | mov.l r8, @-r15 |
339dbf0e | 54 | .Lpush_r8: |
4a17085f | 55 | mov.l r9, @-r15 |
339dbf0e | 56 | .Lpush_r9: |
4a17085f | 57 | mov.l r10, @-r15 |
339dbf0e | 58 | .Lpush_r10: |
4a17085f | 59 | mov.l r12, @-r15 |
339dbf0e | 60 | .Lpush_r12: |
a54e8d33 | 61 | sts.l pr, @-r15 |
339dbf0e | 62 | .Lpush_pr: |
a54e8d33 | 63 | add #-8, r15 |
339dbf0e | 64 | .Lalloc: |
a54e8d33 UD |
65 | mov r4, r8 |
66 | mov r5, r9 | |
67 | ||
68 | /* Check for invalid nanosecond field. */ | |
69 | mov.l @(4,r9), r0 | |
70 | mov.l .L1g, r1 | |
71 | cmp/hs r1, r0 | |
72 | bt/s 6f | |
73 | mov #EINVAL, r0 | |
339dbf0e | 74 | INC (@(NWAITERS,r8),r2) |
4a17085f | 75 | |
339dbf0e | 76 | 7: |
a54e8d33 UD |
77 | /* Compute relative timeout. */ |
78 | mov r15, r4 | |
79 | mov #0, r5 | |
ce31a3b1 | 80 | mov #__NR_gettimeofday, r3 |
a54e8d33 UD |
81 | trapa #0x12 |
82 | SYSCALL_INST_PAD | |
83 | ||
84 | mov.l @(4,r15), r0 | |
85 | mov.w .L1k, r1 | |
86 | dmulu.l r0, r1 /* Milli seconds to nano seconds. */ | |
87 | mov.l @r9, r2 | |
88 | mov.l @(4,r9), r3 | |
89 | mov.l @r15, r0 | |
90 | sts macl, r1 | |
91 | sub r0, r2 | |
92 | clrt | |
93 | subc r1, r3 | |
94 | bf 5f | |
95 | mov.l .L1g, r1 | |
96 | add r1, r3 | |
97 | add #-1, r2 | |
98 | 5: | |
99 | cmp/pz r2 | |
980c14c5 UD |
100 | bf/s 6f /* Time is already up. */ |
101 | mov #ETIMEDOUT, r0 | |
a54e8d33 UD |
102 | |
103 | /* Store relative timeout. */ | |
104 | mov.l r2, @r15 | |
105 | mov.l r3, @(4,r15) | |
106 | ||
339dbf0e UD |
107 | .LcleanupSTART: |
108 | mov.l .Lenable0, r1 | |
109 | bsrf r1 | |
110 | nop | |
111 | .Lenable0b: | |
112 | mov r0, r10 | |
113 | ||
a54e8d33 | 114 | mov r8, r4 |
339dbf0e UD |
115 | #if FUTEX_WAIT == 0 |
116 | mov.l @(PRIVATE,r8), r5 | |
117 | #else | |
118 | mov.l @(PRIVATE,r8), r5 | |
119 | mov #FUTEX_WAIT, r0 | |
120 | or r0, r5 | |
121 | #endif | |
a54e8d33 UD |
122 | mov #0, r6 |
123 | mov r15, r7 | |
124 | mov #SYS_futex, r3 | |
125 | extu.b r3, r3 | |
126 | trapa #0x14 | |
127 | SYSCALL_INST_PAD | |
128 | ||
4a17085f UD |
129 | mov.l .Ldisable0, r1 |
130 | mov r10, r4 | |
131 | bsrf r1 | |
132 | mov r0, r10 | |
d063d164 | 133 | .Ldisable0b: |
4a17085f | 134 | mov r10, r0 |
339dbf0e | 135 | .LcleanupEND: |
4a17085f | 136 | |
a54e8d33 UD |
137 | tst r0, r0 |
138 | bt 9f | |
139 | cmp/eq #-EWOULDBLOCK, r0 | |
140 | bf 3f | |
141 | 9: | |
142 | mov.l @r8, r0 | |
143 | 8: | |
144 | tst r0, r0 | |
145 | bt 7b | |
146 | ||
147 | mov r0, r3 | |
148 | mov r0, r4 | |
149 | add #-1, r3 | |
150 | CMPXCHG (r4, @r8, r3, r2) | |
151 | bf/s 8b | |
152 | mov r2, r0 | |
153 | ||
339dbf0e UD |
154 | DEC (@(NWAITERS,r8), r2) |
155 | mov #0, r0 | |
156 | ||
157 | 10: | |
a54e8d33 UD |
158 | add #8, r15 |
159 | lds.l @r15+, pr | |
a54e8d33 | 160 | mov.l @r15+, r12 |
4a17085f UD |
161 | mov.l @r15+, r10 |
162 | mov.l @r15+, r9 | |
163 | mov.l @r15+, r8 | |
a54e8d33 | 164 | rts |
339dbf0e | 165 | nop |
a54e8d33 UD |
166 | |
167 | 3: | |
168 | neg r0, r0 | |
169 | 6: | |
339dbf0e | 170 | mov r0, r10 |
a54e8d33 UD |
171 | mova .Lgot2, r0 |
172 | mov.l .Lgot2, r12 | |
173 | add r0, r12 | |
174 | ||
a54e8d33 UD |
175 | mov.l .Lerrno2, r0 |
176 | stc gbr, r1 | |
177 | mov.l @(r0, r12), r0 | |
ce31a3b1 UD |
178 | bra .Lexit |
179 | add r1, r0 | |
180 | .align 2 | |
181 | .Lerrno2: | |
d063d164 | 182 | .long errno@GOTTPOFF |
ce31a3b1 | 183 | .Lexit: |
ce31a3b1 | 184 | mov.l r10, @r0 |
339dbf0e UD |
185 | DEC (@(NWAITERS,r8), r2) |
186 | bra 10b | |
a54e8d33 UD |
187 | mov #-1, r0 |
188 | ||
189 | .L1k: | |
190 | .word 1000 | |
191 | .align 2 | |
192 | .L1g: | |
193 | .long 1000000000 | |
194 | .Lgot2: | |
195 | .long _GLOBAL_OFFSET_TABLE_ | |
4a17085f UD |
196 | .Lenable0: |
197 | .long __pthread_enable_asynccancel-.Lenable0b | |
198 | .Ldisable0: | |
199 | .long __pthread_disable_asynccancel-.Ldisable0b | |
a54e8d33 | 200 | .size sem_timedwait,.-sem_timedwait |
339dbf0e UD |
201 | |
202 | .type sem_wait_cleanup,@function | |
203 | sem_wait_cleanup: | |
d063d164 | 204 | DEC (@(NWAITERS,r8), r2) |
339dbf0e UD |
205 | .LcallUR: |
206 | mov.l .Lresume, r1 | |
207 | #ifdef PIC | |
208 | add r12, r1 | |
209 | #endif | |
210 | jsr @r1 | |
211 | nop | |
212 | sleep | |
213 | ||
214 | .align 2 | |
215 | .Lresume: | |
216 | #ifdef PIC | |
217 | .long _Unwind_Resume@GOTOFF | |
218 | #else | |
219 | .long _Unwind_Resume | |
220 | #endif | |
221 | .LENDCODE: | |
222 | .size sem_wait_cleanup,.-sem_wait_cleanup | |
223 | ||
224 | ||
225 | .section .gcc_except_table,"a",@progbits | |
226 | .LexceptSTART: | |
227 | .byte 0xff ! @LPStart format (omit) | |
228 | .byte 0xff ! @TType format (omit) | |
229 | .byte 0x01 ! call-site format | |
230 | ! DW_EH_PE_uleb128 | |
231 | .uleb128 .Lcstend-.Lcstbegin | |
232 | .Lcstbegin: | |
233 | .uleb128 .LcleanupSTART-.LSTARTCODE | |
234 | .uleb128 .LcleanupEND-.LcleanupSTART | |
235 | .uleb128 sem_wait_cleanup-.LSTARTCODE | |
236 | .uleb128 0 | |
237 | .uleb128 .LcallUR-.LSTARTCODE | |
238 | .uleb128 .LENDCODE-.LcallUR | |
239 | .uleb128 0 | |
240 | .uleb128 0 | |
241 | .Lcstend: | |
242 | ||
243 | ||
244 | .section .eh_frame,"a",@progbits | |
245 | .LSTARTFRAME: | |
246 | .ualong .LENDCIE-.LSTARTCIE ! Length of the CIE. | |
247 | .LSTARTCIE: | |
248 | .ualong 0 ! CIE ID. | |
249 | .byte 1 ! Version number. | |
250 | #ifdef SHARED | |
251 | .string "zPLR" ! NUL-terminated augmentation | |
252 | ! string. | |
253 | #else | |
254 | .string "zPL" ! NUL-terminated augmentation | |
255 | ! string. | |
256 | #endif | |
257 | .uleb128 1 ! Code alignment factor. | |
258 | .sleb128 -4 ! Data alignment factor. | |
259 | .byte 0x11 ! Return address register | |
260 | ! column. | |
261 | #ifdef SHARED | |
262 | .uleb128 7 ! Augmentation value length. | |
263 | .byte 0x9b ! Personality: DW_EH_PE_pcrel | |
264 | ! + DW_EH_PE_sdata4 | |
265 | ! + DW_EH_PE_indirect | |
266 | .ualong DW.ref.__gcc_personality_v0-. | |
267 | .byte 0x1b ! LSDA Encoding: DW_EH_PE_pcrel | |
268 | ! + DW_EH_PE_sdata4. | |
269 | .byte 0x1b ! FDE Encoding: DW_EH_PE_pcrel | |
270 | ! + DW_EH_PE_sdata4. | |
271 | #else | |
272 | .uleb128 6 ! Augmentation value length. | |
273 | .byte 0x0 ! Personality: absolute | |
274 | .ualong __gcc_personality_v0 | |
275 | .byte 0x0 ! LSDA Encoding: absolute | |
276 | #endif | |
277 | .byte 0x0c ! DW_CFA_def_cfa | |
278 | .uleb128 0xf | |
279 | .uleb128 0 | |
280 | .align 4 | |
281 | .LENDCIE: | |
282 | ||
283 | .ualong .LENDFDE-.LSTARTFDE ! Length of the FDE. | |
284 | .LSTARTFDE: | |
285 | .ualong .LSTARTFDE-.LSTARTFRAME ! CIE pointer. | |
286 | #ifdef SHARED | |
287 | .ualong .LSTARTCODE-. ! PC-relative start address | |
288 | ! of the code. | |
289 | #else | |
290 | .ualong .LSTARTCODE ! Start address of the code. | |
291 | #endif | |
292 | .ualong .LENDCODE-.LSTARTCODE ! Length of the code. | |
293 | .uleb128 4 ! Augmentation size | |
294 | #ifdef SHARED | |
295 | .ualong .LexceptSTART-. | |
296 | #else | |
297 | .ualong .LexceptSTART | |
298 | #endif | |
299 | ||
300 | .byte 4 ! DW_CFA_advance_loc4 | |
301 | .ualong .Lpush_r8-.LSTARTCODE | |
302 | .byte 14 ! DW_CFA_def_cfa_offset | |
303 | .uleb128 4 | |
304 | .byte 0x88 ! DW_CFA_offset r8 | |
d063d164 | 305 | .uleb128 1 |
339dbf0e UD |
306 | .byte 4 ! DW_CFA_advance_loc4 |
307 | .ualong .Lpush_r9-.Lpush_r8 | |
308 | .byte 14 ! DW_CFA_def_cfa_offset | |
309 | .uleb128 8 | |
310 | .byte 0x89 ! DW_CFA_offset r9 | |
d063d164 | 311 | .uleb128 2 |
339dbf0e UD |
312 | .byte 4 ! DW_CFA_advance_loc4 |
313 | .ualong .Lpush_r10-.Lpush_r9 | |
314 | .byte 14 ! DW_CFA_def_cfa_offset | |
315 | .uleb128 12 | |
316 | .byte 0x8a ! DW_CFA_offset r10 | |
d063d164 | 317 | .uleb128 3 |
339dbf0e UD |
318 | .byte 4 ! DW_CFA_advance_loc4 |
319 | .ualong .Lpush_r12-.Lpush_r10 | |
320 | .byte 14 ! DW_CFA_def_cfa_offset | |
321 | .uleb128 16 | |
322 | .byte 0x8c ! DW_CFA_offset r12 | |
d063d164 | 323 | .uleb128 4 |
339dbf0e UD |
324 | .byte 4 ! DW_CFA_advance_loc4 |
325 | .ualong .Lpush_pr-.Lpush_r12 | |
326 | .byte 14 ! DW_CFA_def_cfa_offset | |
327 | .uleb128 20 | |
328 | .byte 0x91 ! DW_CFA_offset pr | |
329 | .uleb128 5 | |
330 | .byte 4 ! DW_CFA_advance_loc4 | |
331 | .ualong .Lalloc-.Lpush_pr | |
332 | .byte 14 ! DW_CFA_def_cfa_offset | |
333 | .uleb128 28 | |
334 | .align 4 | |
335 | .LENDFDE: | |
336 | ||
337 | ||
338 | #ifdef SHARED | |
339 | .hidden DW.ref.__gcc_personality_v0 | |
340 | .weak DW.ref.__gcc_personality_v0 | |
341 | .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits | |
342 | .align 4 | |
343 | .type DW.ref.__gcc_personality_v0, @object | |
344 | .size DW.ref.__gcc_personality_v0, 4 | |
345 | DW.ref.__gcc_personality_v0: | |
346 | .long __gcc_personality_v0 | |
347 | #endif |