Updated to fedora-glibc-20041006T0900
[kopensolaris-gnu/glibc.git] / nptl / sysdeps / unix / sysv / linux / x86_64 / sem_wait.S
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.
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_futex               202
31
32
33         .text
34
35         .globl  sem_wait
36         .type   sem_wait,@function
37         .align  16
38         cfi_startproc
39 sem_wait:
40         /* First check for cancellation.  */
41         movl    %fs:CANCELHANDLING, %eax
42         andl    $0xfffffff9, %eax
43         cmpl    $8, %eax
44         je      4f
45
46         pushq   %r12
47         cfi_adjust_cfa_offset(8)
48         cfi_offset(12, -16)
49         pushq   %r13
50         cfi_adjust_cfa_offset(8)
51         movq    %rdi, %r13
52         cfi_offset(13, -24)
53
54 3:      movl    (%r13), %eax
55 2:      testl   %eax, %eax
56         je      1f
57
58         leaq    -1(%rax), %rdx
59         LOCK
60         cmpxchgl %edx, (%r13)
61         jne     2b
62         xorl    %eax, %eax
63
64         popq    %r13
65         cfi_adjust_cfa_offset(-8)
66         cfi_restore(13)
67         popq    %r12
68         cfi_adjust_cfa_offset(-8)
69         cfi_restore(12)
70
71         retq
72
73         cfi_adjust_cfa_offset(16)
74         cfi_offset(12, -16)
75         cfi_offset(13, -24)
76 1:      call    __pthread_enable_asynccancel
77         movl    %eax, %r8d
78
79         xorq    %r10, %r10
80         movq    $SYS_futex, %rax
81         movq    %r13, %rdi
82         movq    %r10, %rsi
83         movq    %r10, %rdx
84         syscall
85         movq    %rax, %r12
86
87         movl    %r8d, %edi
88         call    __pthread_disable_asynccancel
89
90         testq   %r12, %r12
91         je      3b
92         cmpq    $-EWOULDBLOCK, %r12
93         je      3b
94         negq    %r12
95 #if USE___THREAD
96         movq    errno@gottpoff(%rip), %rdx
97         movl    %r12d, %fs:(%rdx)
98 #else
99         callq   __errno_location@plt
100         movl    %r12d, (%rax)
101 #endif
102         orl     $-1, %eax
103
104         popq    %r13
105         cfi_adjust_cfa_offset(-8)
106         cfi_restore(13)
107         popq    %r12
108         cfi_adjust_cfa_offset(-8)
109         cfi_restore(12)
110
111         retq
112
113 4:      /* Canceled.  */
114         movq    $0xffffffffffffffff, %fs:RESULT
115         LOCK
116         orl     $0x10, %fs:CANCELHANDLING
117         movq    %fs:CLEANUP_JMP_BUF, %rdi
118         jmp     HIDDEN_JUMPTARGET (__pthread_unwind)
119         cfi_endproc
120         .size   sem_wait,.-sem_wait