Update copyright notices with scripts/update-copyrights
[glibc.git] / nptl / sysdeps / unix / sysv / linux / i386 / i486 / lowlevelrobustlock.S
blob1b2933dadc2938481d2219bf06f996f8b514c6be
1 /* Copyright (C) 2002-2014 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, see
17    <http://www.gnu.org/licenses/>.  */
19 #include <sysdep.h>
20 #include <pthread-errnos.h>
21 #include <lowlevellock.h>
22 #include <lowlevelrobustlock.h>
23 #include <kernel-features.h>
25         .text
27 #define FUTEX_WAITERS           0x80000000
28 #define FUTEX_OWNER_DIED        0x40000000
30 #ifdef __ASSUME_PRIVATE_FUTEX
31 # define LOAD_FUTEX_WAIT(reg) \
32         xorl    $(FUTEX_WAIT | FUTEX_PRIVATE_FLAG), reg
33 #else
34 # if FUTEX_WAIT == 0
35 #  define LOAD_FUTEX_WAIT(reg) \
36         xorl    $FUTEX_PRIVATE_FLAG, reg ; \
37         andl    %gs:PRIVATE_FUTEX, reg
38 # else
39 #  define LOAD_FUTEX_WAIT(reg) \
40         xorl    $FUTEX_PRIVATE_FLAG, reg ; \
41         andl    %gs:PRIVATE_FUTEX, reg ; \
42         orl     $FUTEX_WAIT, reg
43 # endif
44 #endif
46         .globl  __lll_robust_lock_wait
47         .type   __lll_robust_lock_wait,@function
48         .hidden __lll_robust_lock_wait
49         .align  16
50 __lll_robust_lock_wait:
51         cfi_startproc
52         pushl   %edx
53         cfi_adjust_cfa_offset(4)
54         pushl   %ebx
55         cfi_adjust_cfa_offset(4)
56         pushl   %esi
57         cfi_adjust_cfa_offset(4)
58         cfi_offset(%edx, -8)
59         cfi_offset(%ebx, -12)
60         cfi_offset(%esi, -16)
62         movl    %edx, %ebx
63         xorl    %esi, %esi      /* No timeout.  */
64         LOAD_FUTEX_WAIT (%ecx)
66 4:      movl    %eax, %edx
67         orl     $FUTEX_WAITERS, %edx
69         testl   $FUTEX_OWNER_DIED, %eax
70         jnz     3f
72         cmpl    %edx, %eax      /* NB:   %edx == 2 */
73         je      1f
75         LOCK
76         cmpxchgl %edx, (%ebx)
77         jnz     2f
79 1:      movl    $SYS_futex, %eax
80         ENTER_KERNEL
82         movl    (%ebx), %eax
84 2:      test    %eax, %eax
85         jne     4b
87         movl    %gs:TID, %edx
88         orl     $FUTEX_WAITERS, %edx
89         LOCK
90         cmpxchgl %edx, (%ebx)
91         jnz     4b
92         /* NB:   %eax == 0 */
94 3:      popl    %esi
95         cfi_adjust_cfa_offset(-4)
96         cfi_restore(%esi)
97         popl    %ebx
98         cfi_adjust_cfa_offset(-4)
99         cfi_restore(%ebx)
100         popl    %edx
101         cfi_adjust_cfa_offset(-4)
102         cfi_restore(%edx)
103         ret
104         cfi_endproc
105         .size   __lll_robust_lock_wait,.-__lll_robust_lock_wait
108         .globl  __lll_robust_timedlock_wait
109         .type   __lll_robust_timedlock_wait,@function
110         .hidden __lll_robust_timedlock_wait
111         .align  16
112 __lll_robust_timedlock_wait:
113         cfi_startproc
114         /* Check for a valid timeout value.  */
115         cmpl    $1000000000, 4(%edx)
116         jae     3f
118         pushl   %edi
119         cfi_adjust_cfa_offset(4)
120         pushl   %esi
121         cfi_adjust_cfa_offset(4)
122         pushl   %ebx
123         cfi_adjust_cfa_offset(4)
124         pushl   %ebp
125         cfi_adjust_cfa_offset(4)
126         cfi_offset(%edi, -8)
127         cfi_offset(%esi, -12)
128         cfi_offset(%ebx, -16)
129         cfi_offset(%ebp, -20)
131         /* Stack frame for the timespec and timeval structs.  */
132         subl    $12, %esp
133         cfi_adjust_cfa_offset(12)
135         movl    %ecx, %ebp
136         movl    %edx, %edi
138 1:      movl    %eax, 8(%esp)
140         /* Get current time.  */
141         movl    %esp, %ebx
142         xorl    %ecx, %ecx
143         movl    $__NR_gettimeofday, %eax
144         ENTER_KERNEL
146         /* Compute relative timeout.  */
147         movl    4(%esp), %eax
148         movl    $1000, %edx
149         mul     %edx            /* Milli seconds to nano seconds.  */
150         movl    (%edi), %ecx
151         movl    4(%edi), %edx
152         subl    (%esp), %ecx
153         subl    %eax, %edx
154         jns     4f
155         addl    $1000000000, %edx
156         subl    $1, %ecx
157 4:      testl   %ecx, %ecx
158         js      8f              /* Time is already up.  */
160         /* Store relative timeout.  */
161         movl    %ecx, (%esp)
162         movl    %edx, 4(%esp)
164         movl    %ebp, %ebx
166         movl    8(%esp), %edx
167         movl    %edx, %eax
168         orl     $FUTEX_WAITERS, %edx
170         testl   $FUTEX_OWNER_DIED, %eax
171         jnz     6f
173         cmpl    %eax, %edx
174         je      2f
176         LOCK
177         cmpxchgl %edx, (%ebx)
178         movl    $0, %ecx        /* Must use mov to avoid changing cc.  */
179         jnz     5f
182         /* Futex call.  */
183         movl    %esp, %esi
184         movl    20(%esp), %ecx
185         LOAD_FUTEX_WAIT (%ecx)
186         movl    $SYS_futex, %eax
187         ENTER_KERNEL
188         movl    %eax, %ecx
190         movl    (%ebx), %eax
192 5:      testl   %eax, %eax
193         jne     7f
195         movl    %gs:TID, %edx
196         orl     $FUTEX_WAITERS, %edx
197         LOCK
198         cmpxchgl %edx, (%ebx)
199         jnz     7f
201 6:      addl    $12, %esp
202         cfi_adjust_cfa_offset(-12)
203         popl    %ebp
204         cfi_adjust_cfa_offset(-4)
205         cfi_restore(%ebp)
206         popl    %ebx
207         cfi_adjust_cfa_offset(-4)
208         cfi_restore(%ebx)
209         popl    %esi
210         cfi_adjust_cfa_offset(-4)
211         cfi_restore(%esi)
212         popl    %edi
213         cfi_adjust_cfa_offset(-4)
214         cfi_restore(%edi)
215         ret
217 3:      movl    $EINVAL, %eax
218         ret
220         cfi_adjust_cfa_offset(28)
221         cfi_offset(%edi, -8)
222         cfi_offset(%esi, -12)
223         cfi_offset(%ebx, -16)
224         cfi_offset(%ebp, -20)
225         /* Check whether the time expired.  */
226 7:      cmpl    $-ETIMEDOUT, %ecx
227         jne     1b
229 8:      movl    $ETIMEDOUT, %eax
230         jmp     6b
231         cfi_endproc
232         .size   __lll_robust_timedlock_wait,.-__lll_robust_timedlock_wait