(CFLAGS-tst-align.c): Add -mpreferred-stack-boundary=4.
[glibc.git] / nptl / sysdeps / unix / sysv / linux / i386 / i486 / sem_timedwait.S
blob5b244769361ae3cd79c9f5158113e7e275ea81cd
1 /* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
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.
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.
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.  */
20 #include <sysdep.h>
21 #include <shlib-compat.h>
22 #include <pthread-errnos.h>
24 #ifndef UP
25 # define LOCK lock
26 #else
27 # define
28 #endif
30 #define SYS_gettimeofday        __NR_gettimeofday
31 #define SYS_futex               240
32 #define FUTEX_WAKE              1
35         .text
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
48         movl    4(%esp), %ecx
50         movl    (%ecx), %eax
51 2:      testl   %eax, %eax
52         je,pn   1f
54         leal    -1(%eax), %edx
55         LOCK
56         cmpxchgl %edx, (%ecx)
57         jne,pn  2b
59         xorl    %eax, %eax
60         ret
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)
72         movl    32(%esp), %edi
73         cfi_offset(7, -12)              /* %edi */
75         /* Check for invalid nanosecond field.  */
76         cmpl    $1000000000, 4(%edi)
77         movl    $EINVAL, %esi
78         cfi_offset(6, -8)               /* %esi */
79         jae     6f
81         cfi_offset(3, -16)              /* %ebx */
82 7:      call    __pthread_enable_asynccancel
83         movl    %eax, 8(%esp)
85         xorl    %ecx, %ecx
86         movl    %esp, %ebx
87         movl    %ecx, %edx
88         movl    $SYS_gettimeofday, %eax
89         ENTER_KERNEL
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
101         subl    $1, %ecx
102 5:      testl   %ecx, %ecx
103         movl    $ETIMEDOUT, %esi
104         js      6f              /* Time is already up.  */
106         movl    %ecx, (%esp)    /* Store relative timeout.  */
107         movl    %edx, 4(%esp)
108         movl    28(%esp), %ebx
109         xorl    %ecx, %ecx
110         movl    %esp, %esi
111         movl    $SYS_futex, %eax
112         xorl    %edx, %edx
113         ENTER_KERNEL
114         movl    %eax, %esi
116         movl    8(%esp), %eax
117         call    __pthread_disable_asynccancel
119         testl   %esi, %esi
120         je,pt   9f
121         cmpl    $-EWOULDBLOCK, %esi
122         jne     3f
124 9:      movl    (%ebx), %eax
125 8:      testl   %eax, %eax
126         je      7b
128         leal    -1(%eax), %ecx
129         LOCK
130         cmpxchgl %ecx, (%ebx)
131         jne,pn  8b
133         addl    $12, %esp
134         cfi_adjust_cfa_offset(-12)
135         xorl    %eax, %eax
136         popl    %ebx
137         cfi_adjust_cfa_offset(-4)
138         cfi_restore(3)
139         popl    %edi
140         cfi_adjust_cfa_offset(-4)
141         cfi_restore(7)
142         popl    %esi
143         cfi_adjust_cfa_offset(-4)
144         cfi_restore(6)
145         ret
147         cfi_adjust_cfa_offset(24)
148         cfi_offset(6, -8)               /* %esi */
149         cfi_offset(7, -12)              /* %edi */
150         cfi_offset(3, -16)              /* %ebx */
151 3:      negl    %esi
153 #ifdef PIC
154         call    __i686.get_pc_thunk.bx
155 #else
156         movl    $4f, %ebx
158 #endif
159         addl    $_GLOBAL_OFFSET_TABLE_, %ebx
160 #if USE___THREAD
161         movl    %gs:0, %edx
162         subl    errno@gottpoff(%ebx), %edx
163         movl    %esi, (%edx)
164 #else
165         call    __errno_location@plt
166         movl    %esi, (%eax)
167 #endif
169         addl    $12, %esp
170         cfi_adjust_cfa_offset(-12)
171         orl     $-1, %eax
172         popl    %ebx
173         cfi_adjust_cfa_offset(-4)
174         cfi_restore(3)
175         popl    %edi
176         cfi_adjust_cfa_offset(-4)
177         cfi_restore(7)
178         popl    %esi
179         cfi_adjust_cfa_offset(-4)
180         cfi_restore(6)
181         ret
183 10:     /* Canceled.  */
184         movl    $0xffffffff, %gs:RESULT
185         LOCK
186         orl     $0x10, %gs:CANCELHANDLING
187         movl    %gs:CLEANUP_JMP_BUF, %eax
188         jmp     HIDDEN_JUMPTARGET (__pthread_unwind)
189         cfi_endproc
190         .size   sem_timedwait,.-sem_timedwait