]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/uclibc/lib/contrib/uclibc/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S
update
[l4.git] / l4 / pkg / uclibc / lib / contrib / uclibc / libpthread / nptl / sysdeps / unix / sysv / linux / x86_64 / sem_wait.S
1 /* Copyright (C) 2002, 2003, 2005, 2007, 2009 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 <lowlevellock.h>
22 #include <pthread-errnos.h>
23 #include <structsem.h>
24
25
26         .text
27
28         .globl  sem_wait
29         .type   sem_wait,@function
30         .align  16
31 sem_wait:
32 .LSTARTCODE:
33         cfi_startproc
34
35 #if VALUE == 0
36         movl    (%rdi), %eax
37 #else
38         movl    VALUE(%rdi), %eax
39 #endif
40 2:      testl   %eax, %eax
41         je      1f
42
43         leal    -1(%rax), %edx
44         LOCK
45 #if VALUE == 0
46         cmpxchgl %edx, (%rdi)
47 #else
48         cmpxchgl %edx, VALUE(%rdi)
49 #endif
50         jne     2b
51
52         xorl    %eax, %eax
53         retq
54
55         /* This push is only needed to store the sem_t pointer for the
56            exception handler.  */
57 1:      pushq   %rdi
58         cfi_adjust_cfa_offset(8)
59
60         LOCK
61         addq    $1, NWAITERS(%rdi)
62
63 .LcleanupSTART:
64 6:      call    __pthread_enable_asynccancel
65         movl    %eax, %r8d
66
67         xorq    %r10, %r10
68         movl    $SYS_futex, %eax
69 #if FUTEX_WAIT == 0
70         movl    PRIVATE(%rdi), %esi
71 #else
72         movl    $FUTEX_WAIT, %esi
73         orl     PRIVATE(%rdi), %esi
74 #endif
75         xorl    %edx, %edx
76         syscall
77         movq    %rax, %rcx
78
79         xchgq   %r8, %rdi
80         call    __pthread_disable_asynccancel
81 .LcleanupEND:
82         movq    %r8, %rdi
83
84         testq   %rcx, %rcx
85         je      3f
86         cmpq    $-EWOULDBLOCK, %rcx
87         jne     4f
88
89 3:
90 #if VALUE == 0
91         movl    (%rdi), %eax
92 #else
93         movl    VALUE(%rdi), %eax
94 #endif
95 5:      testl   %eax, %eax
96         je      6b
97
98         leal    -1(%rax), %edx
99         LOCK
100 #if VALUE == 0
101         cmpxchgl %edx, (%rdi)
102 #else
103         cmpxchgl %edx, VALUE(%rdi)
104 #endif
105         jne     5b
106
107         xorl    %eax, %eax
108
109 9:      LOCK
110         subq    $1, NWAITERS(%rdi)
111
112         leaq    8(%rsp), %rsp
113         cfi_adjust_cfa_offset(-8)
114
115         retq
116
117         cfi_adjust_cfa_offset(8)
118 4:      negq    %rcx
119 #if USE___THREAD
120         movq    errno@gottpoff(%rip), %rdx
121         movl    %ecx, %fs:(%rdx)
122 #else
123 # error "not supported.  %rcx and %rdi must be preserved"
124         callq   __errno_location@plt
125         movl    %ecx, (%rax)
126 #endif
127         orl     $-1, %eax
128
129         jmp 9b
130         .size   sem_wait,.-sem_wait
131
132
133         .type   sem_wait_cleanup,@function
134 sem_wait_cleanup:
135         movq    (%rsp), %rdi
136         LOCK
137         subq    $1, NWAITERS(%rdi)
138         movq    %rax, %rdi
139 .LcallUR:
140         call    _Unwind_Resume@PLT
141         hlt
142 .LENDCODE:
143         cfi_endproc
144         .size   sem_wait_cleanup,.-sem_wait_cleanup
145
146
147         .section .gcc_except_table,"a",@progbits
148 .LexceptSTART:
149         .byte   DW_EH_PE_omit                   # @LPStart format
150         .byte   DW_EH_PE_omit                   # @TType format
151         .byte   DW_EH_PE_uleb128                # call-site format
152         .uleb128 .Lcstend-.Lcstbegin
153 .Lcstbegin:
154         .uleb128 .LcleanupSTART-.LSTARTCODE
155         .uleb128 .LcleanupEND-.LcleanupSTART
156         .uleb128 sem_wait_cleanup-.LSTARTCODE
157         .uleb128  0
158         .uleb128 .LcallUR-.LSTARTCODE
159         .uleb128 .LENDCODE-.LcallUR
160         .uleb128 0
161         .uleb128  0
162 .Lcstend:
163
164
165 #ifdef SHARED
166         .hidden DW.ref.__gcc_personality_v0
167         .weak   DW.ref.__gcc_personality_v0
168         .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
169         .align  8
170         .type   DW.ref.__gcc_personality_v0, @object
171         .size   DW.ref.__gcc_personality_v0, 8
172 DW.ref.__gcc_personality_v0:
173         .quad   __gcc_personality_v0
174 #endif