(CFLAGS-tst-align.c): Add -mpreferred-stack-boundary=4.
[glibc.git] / nptl / sysdeps / unix / sysv / linux / i386 / i486 / sem_wait.S
blobb7674dc3baf85e0574a7fefd0a1245decd8ad4fb
1 /* Copyright (C) 2002, 2003 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_futex               240
31 #define FUTEX_WAKE              1
34         .text
36         .globl  __new_sem_wait
37         .type   __new_sem_wait,@function
38         .align  16
39         cfi_startproc
40 __new_sem_wait:
41         /* First check for cancellation.  */
42         movl    %gs:CANCELHANDLING, %eax
43         andl    $0xfffffff9, %eax
44         cmpl    $8, %eax
45         je      5f
47         pushl   %ebx
48         cfi_adjust_cfa_offset(4)
49         pushl   %esi
50         cfi_adjust_cfa_offset(4)
51         subl    $4, %esp
52         cfi_adjust_cfa_offset(4)
54         movl    16(%esp), %ebx
55         cfi_offset(3, -8)               /* %ebx */
57         cfi_offset(6, -12)              /* %esi */
58 3:      movl    (%ebx), %eax
59 2:      testl   %eax, %eax
60         je,pn   1f
62         leal    -1(%eax), %edx
63         LOCK
64         cmpxchgl %edx, (%ebx)
65         jne,pn  2b
66         xorl    %eax, %eax
68         movl    4(%esp), %esi
69         cfi_restore(6)
70         movl    8(%esp), %ebx
71         cfi_restore(3)
72         addl    $12, %esp
73         cfi_adjust_cfa_offset(-12)
74         ret
76         cfi_adjust_cfa_offset(8)
77         cfi_offset(3, -8)               /* %ebx */
78         cfi_offset(6, -12)              /* %esi */
79 1:      call    __pthread_enable_asynccancel
80         movl    %eax, (%esp)
82         xorl    %esi, %esi
83         movl    $SYS_futex, %eax
84         movl    %esi, %ecx
85         movl    %esi, %edx
86         ENTER_KERNEL
87         movl    %eax, %esi
89         movl    (%esp), %eax
90         call    __pthread_disable_asynccancel
92         testl   %esi, %esi
93         je      3b
94         cmpl    $-EWOULDBLOCK, %esi
95         je      3b
96         negl    %esi
97 #ifdef PIC
98         call    __i686.get_pc_thunk.bx
99 #else
100         movl    $4f, %ebx
102 #endif
103         addl    $_GLOBAL_OFFSET_TABLE_, %ebx
104 #if USE___THREAD
105         movl    %gs:0, %edx
106         subl    errno@gottpoff(%ebx), %edx
107         movl    %esi, (%edx)
108 #else
109         call    __errno_location@plt
110         movl    %esi, (%eax)
111 #endif
112         orl     $-1, %eax
113         movl    4(%esp), %esi
114         cfi_restore(6)
115         movl    8(%esp), %ebx
116         cfi_restore(3)
117         addl    $12, %esp
118         cfi_adjust_cfa_offset(-12)
119         ret
121 5:      /* Canceled.  */
122         movl    $0xffffffff, %gs:RESULT
123         LOCK
124         orl     $0x10, %gs:CANCELHANDLING
125         movl    %gs:CLEANUP_JMP_BUF, %eax
126         jmp     HIDDEN_JUMPTARGET (__pthread_unwind)
127         cfi_endproc
128         .size   __new_sem_wait,.-__new_sem_wait
129         versioned_symbol(libpthread, __new_sem_wait, sem_wait, GLIBC_2_1)
130 #if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
131         .global __old_sem_wait
132 __old_sem_wait = __new_sem_wait
133         compat_symbol(libpthread, __old_sem_wait, sem_wait, GLIBC_2_0)
134 #endif