nptl: Remove __ASSUME_PRIVATE_FUTEX
[glibc.git] / sysdeps / unix / sysv / linux / i386 / lowlevellock.S
blobfeda390eeb1cf3c363efbb4bc3b36cfcf8206c28
1 /* Copyright (C) 2002-2018 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 <kernel-features.h>
22 #include <lowlevellock.h>
24 #include <stap-probe.h>
26         .text
28 #define LOAD_PRIVATE_FUTEX_WAIT(reg) \
29         movl    $(FUTEX_WAIT | FUTEX_PRIVATE_FLAG), reg
30 #define LOAD_PRIVATE_FUTEX_WAKE(reg) \
31         movl    $(FUTEX_WAKE | FUTEX_PRIVATE_FLAG), reg
32 #define LOAD_FUTEX_WAIT(reg) \
33         xorl    $(FUTEX_WAIT | FUTEX_PRIVATE_FLAG), reg
34 #define LOAD_FUTEX_WAIT_ABS(reg) \
35         xorl    $(FUTEX_WAIT_BITSET | FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME), reg
36 #define LOAD_FUTEX_WAKE(reg) \
37         xorl    $(FUTEX_WAKE | FUTEX_PRIVATE_FLAG), reg
39         .globl  __lll_lock_wait_private
40         .type   __lll_lock_wait_private,@function
41         .hidden __lll_lock_wait_private
42         .align  16
43 __lll_lock_wait_private:
44         cfi_startproc
45         pushl   %edx
46         cfi_adjust_cfa_offset(4)
47         pushl   %ebx
48         cfi_adjust_cfa_offset(4)
49         pushl   %esi
50         cfi_adjust_cfa_offset(4)
51         cfi_offset(%edx, -8)
52         cfi_offset(%ebx, -12)
53         cfi_offset(%esi, -16)
55         movl    $2, %edx
56         movl    %ecx, %ebx
57         xorl    %esi, %esi      /* No timeout.  */
58         LOAD_PRIVATE_FUTEX_WAIT (%ecx)
60         cmpl    %edx, %eax      /* NB:   %edx == 2 */
61         jne 2f
63 1:      LIBC_PROBE (lll_lock_wait_private, 1, %ebx)
64         movl    $SYS_futex, %eax
65         ENTER_KERNEL
67 2:      movl    %edx, %eax
68         xchgl   %eax, (%ebx)    /* NB:   lock is implied */
70         testl   %eax, %eax
71         jnz     1b
73         popl    %esi
74         cfi_adjust_cfa_offset(-4)
75         cfi_restore(%esi)
76         popl    %ebx
77         cfi_adjust_cfa_offset(-4)
78         cfi_restore(%ebx)
79         popl    %edx
80         cfi_adjust_cfa_offset(-4)
81         cfi_restore(%edx)
82         ret
83         cfi_endproc
84         .size   __lll_lock_wait_private,.-__lll_lock_wait_private
86 #if !IS_IN (libc)
87         .globl  __lll_lock_wait
88         .type   __lll_lock_wait,@function
89         .hidden __lll_lock_wait
90         .align  16
91 __lll_lock_wait:
92         cfi_startproc
93         pushl   %edx
94         cfi_adjust_cfa_offset(4)
95         pushl   %ebx
96         cfi_adjust_cfa_offset(4)
97         pushl   %esi
98         cfi_adjust_cfa_offset(4)
99         cfi_offset(%edx, -8)
100         cfi_offset(%ebx, -12)
101         cfi_offset(%esi, -16)
103         movl    %edx, %ebx
104         movl    $2, %edx
105         xorl    %esi, %esi      /* No timeout.  */
106         LOAD_FUTEX_WAIT (%ecx)
108         cmpl    %edx, %eax      /* NB:   %edx == 2 */
109         jne 2f
111 1:      movl    $SYS_futex, %eax
112         ENTER_KERNEL
114 2:      movl    %edx, %eax
115         xchgl   %eax, (%ebx)    /* NB:   lock is implied */
117         testl   %eax, %eax
118         jnz     1b
120         popl    %esi
121         cfi_adjust_cfa_offset(-4)
122         cfi_restore(%esi)
123         popl    %ebx
124         cfi_adjust_cfa_offset(-4)
125         cfi_restore(%ebx)
126         popl    %edx
127         cfi_adjust_cfa_offset(-4)
128         cfi_restore(%edx)
129         ret
130         cfi_endproc
131         .size   __lll_lock_wait,.-__lll_lock_wait
133         /*      %ecx: futex
134                 %esi: flags
135                 %edx: timeout
136                 %eax: futex value
137         */
138         .globl  __lll_timedlock_wait
139         .type   __lll_timedlock_wait,@function
140         .hidden __lll_timedlock_wait
141         .align  16
142 __lll_timedlock_wait:
143         cfi_startproc
144         pushl   %ebp
145         cfi_adjust_cfa_offset(4)
146         cfi_rel_offset(%ebp, 0)
147         pushl   %ebx
148         cfi_adjust_cfa_offset(4)
149         cfi_rel_offset(%ebx, 0)
151 # ifndef __ASSUME_FUTEX_CLOCK_REALTIME
152 #  ifdef PIC
153         LOAD_PIC_REG (bx)
154         cmpl    $0, __have_futex_clock_realtime@GOTOFF(%ebx)
155 #  else
156         cmpl    $0, __have_futex_clock_realtime
157 #  endif
158         je      .Lreltmo
159 # endif
161         cmpl    $0, (%edx)
162         js      8f
164         movl    %ecx, %ebx
165         movl    %esi, %ecx
166         movl    %edx, %esi
167         movl    $0xffffffff, %ebp
168         LOAD_FUTEX_WAIT_ABS (%ecx)
170         movl    $2, %edx
171         cmpl    %edx, %eax
172         jne     2f
174 1:      movl    $SYS_futex, %eax
175         movl    $2, %edx
176         ENTER_KERNEL
178 2:      xchgl   %edx, (%ebx)    /* NB:   lock is implied */
180         testl   %edx, %edx
181         jz      3f
183         cmpl    $-ETIMEDOUT, %eax
184         je      4f
185         cmpl    $-EINVAL, %eax
186         jne     1b
187 4:      movl    %eax, %edx
188         negl    %edx
190 3:      movl    %edx, %eax
191 7:      popl    %ebx
192         cfi_adjust_cfa_offset(-4)
193         cfi_restore(%ebx)
194         popl    %ebp
195         cfi_adjust_cfa_offset(-4)
196         cfi_restore(%ebp)
197         ret
199 8:      movl    $ETIMEDOUT, %eax
200         jmp     7b
202 # ifndef __ASSUME_FUTEX_CLOCK_REALTIME
203 .Lreltmo:
204         /* Check for a valid timeout value.  */
205         cmpl    $1000000000, 4(%edx)
206         jae     3f
208         pushl   %esi
209         cfi_adjust_cfa_offset(4)
210         cfi_rel_offset(%esi, 0)
211         pushl   %edi
212         cfi_adjust_cfa_offset(4)
213         cfi_rel_offset(%edi, 0)
215         /* Stack frame for the timespec and timeval structs.  */
216         subl    $8, %esp
217         cfi_adjust_cfa_offset(8)
219         movl    %ecx, %ebp
220         movl    %edx, %edi
222         movl    $2, %edx
223         xchgl   %edx, (%ebp)
225         test    %edx, %edx
226         je      6f
229         /* Get current time.  */
230         movl    %esp, %ebx
231         xorl    %ecx, %ecx
232         movl    $__NR_gettimeofday, %eax
233         ENTER_KERNEL
235         /* Compute relative timeout.  */
236         movl    4(%esp), %eax
237         movl    $1000, %edx
238         mul     %edx            /* Milli seconds to nano seconds.  */
239         movl    (%edi), %ecx
240         movl    4(%edi), %edx
241         subl    (%esp), %ecx
242         subl    %eax, %edx
243         jns     4f
244         addl    $1000000000, %edx
245         subl    $1, %ecx
246 4:      testl   %ecx, %ecx
247         js      2f              /* Time is already up.  */
249         /* Store relative timeout.  */
250         movl    %ecx, (%esp)
251         movl    %edx, 4(%esp)
253         /* Futex call.  */
254         movl    %ebp, %ebx
255         movl    $2, %edx
256         movl    %esp, %esi
257         movl    16(%esp), %ecx
258         LOAD_FUTEX_WAIT (%ecx)
259         movl    $SYS_futex, %eax
260         ENTER_KERNEL
262         /* NB: %edx == 2 */
263         xchgl   %edx, (%ebp)
265         testl   %edx, %edx
266         je      6f
268         cmpl    $-ETIMEDOUT, %eax
269         jne     1b
270 2:      movl    $ETIMEDOUT, %edx
272 6:      addl    $8, %esp
273         cfi_adjust_cfa_offset(-8)
274         popl    %edi
275         cfi_adjust_cfa_offset(-4)
276         cfi_restore(%edi)
277         popl    %esi
278         cfi_adjust_cfa_offset(-4)
279         cfi_restore(%esi)
280 7:      popl    %ebx
281         cfi_adjust_cfa_offset(-4)
282         cfi_restore(%ebx)
283         popl    %ebp
284         cfi_adjust_cfa_offset(-4)
285         cfi_restore(%ebp)
286         movl    %edx, %eax
287         ret
289 3:      movl    $EINVAL, %edx
290         jmp     7b
291 # endif
292         cfi_endproc
293         .size   __lll_timedlock_wait,.-__lll_timedlock_wait
294 #endif
296         .globl  __lll_unlock_wake_private
297         .type   __lll_unlock_wake_private,@function
298         .hidden __lll_unlock_wake_private
299         .align  16
300 __lll_unlock_wake_private:
301         cfi_startproc
302         pushl   %ebx
303         cfi_adjust_cfa_offset(4)
304         pushl   %ecx
305         cfi_adjust_cfa_offset(4)
306         pushl   %edx
307         cfi_adjust_cfa_offset(4)
308         cfi_offset(%ebx, -8)
309         cfi_offset(%ecx, -12)
310         cfi_offset(%edx, -16)
312         movl    %eax, %ebx
313         movl    $0, (%eax)
314         LOAD_PRIVATE_FUTEX_WAKE (%ecx)
315         movl    $1, %edx        /* Wake one thread.  */
316         movl    $SYS_futex, %eax
317         ENTER_KERNEL
319         popl    %edx
320         cfi_adjust_cfa_offset(-4)
321         cfi_restore(%edx)
322         popl    %ecx
323         cfi_adjust_cfa_offset(-4)
324         cfi_restore(%ecx)
325         popl    %ebx
326         cfi_adjust_cfa_offset(-4)
327         cfi_restore(%ebx)
328         ret
329         cfi_endproc
330         .size   __lll_unlock_wake_private,.-__lll_unlock_wake_private
332 #if !IS_IN (libc)
333         .globl  __lll_unlock_wake
334         .type   __lll_unlock_wake,@function
335         .hidden __lll_unlock_wake
336         .align  16
337 __lll_unlock_wake:
338         cfi_startproc
339         pushl   %ebx
340         cfi_adjust_cfa_offset(4)
341         pushl   %ecx
342         cfi_adjust_cfa_offset(4)
343         pushl   %edx
344         cfi_adjust_cfa_offset(4)
345         cfi_offset(%ebx, -8)
346         cfi_offset(%ecx, -12)
347         cfi_offset(%edx, -16)
349         movl    %eax, %ebx
350         movl    $0, (%eax)
351         LOAD_FUTEX_WAKE (%ecx)
352         movl    $1, %edx        /* Wake one thread.  */
353         movl    $SYS_futex, %eax
354         ENTER_KERNEL
356         popl    %edx
357         cfi_adjust_cfa_offset(-4)
358         cfi_restore(%edx)
359         popl    %ecx
360         cfi_adjust_cfa_offset(-4)
361         cfi_restore(%ecx)
362         popl    %ebx
363         cfi_adjust_cfa_offset(-4)
364         cfi_restore(%ebx)
365         ret
366         cfi_endproc
367         .size   __lll_unlock_wake,.-__lll_unlock_wake
369         .globl  __lll_timedwait_tid
370         .type   __lll_timedwait_tid,@function
371         .hidden __lll_timedwait_tid
372         .align  16
373 __lll_timedwait_tid:
374         pushl   %edi
375         pushl   %esi
376         pushl   %ebx
377         pushl   %ebp
379         movl    %eax, %ebp
380         movl    %edx, %edi
381         subl    $8, %esp
383         /* Get current time.  */
384 2:      movl    %esp, %ebx
385         xorl    %ecx, %ecx
386         movl    $__NR_gettimeofday, %eax
387         ENTER_KERNEL
389         /* Compute relative timeout.  */
390         movl    4(%esp), %eax
391         movl    $1000, %edx
392         mul     %edx            /* Milli seconds to nano seconds.  */
393         movl    (%edi), %ecx
394         movl    4(%edi), %edx
395         subl    (%esp), %ecx
396         subl    %eax, %edx
397         jns     5f
398         addl    $1000000000, %edx
399         subl    $1, %ecx
400 5:      testl   %ecx, %ecx
401         js      6f              /* Time is already up.  */
403         movl    %ecx, (%esp)    /* Store relative timeout.  */
404         movl    %edx, 4(%esp)
406         movl    (%ebp), %edx
407         testl   %edx, %edx
408         jz      4f
410         movl    %esp, %esi
411         /* XXX The kernel so far uses global futex for the wakeup at
412            all times.  */
413         xorl    %ecx, %ecx      /* movl $FUTEX_WAIT, %ecx */
414         movl    %ebp, %ebx
415         movl    $SYS_futex, %eax
416         ENTER_KERNEL
418         cmpl    $0, (%ebx)
419         jne     1f
420 4:      xorl    %eax, %eax
422 3:      addl    $8, %esp
423         popl    %ebp
424         popl    %ebx
425         popl    %esi
426         popl    %edi
427         ret
429 1:      cmpl    $-ETIMEDOUT, %eax
430         jne     2b
431 6:      movl    $ETIMEDOUT, %eax
432         jmp     3b
433         .size   __lll_timedwait_tid,.-__lll_timedwait_tid
434 #endif