diff options
author | Waldemar Brodkorb <wbx@openadk.org> | 2017-12-15 21:34:23 +0100 |
---|---|---|
committer | Waldemar Brodkorb <wbx@openadk.org> | 2017-12-16 20:47:46 +0100 |
commit | a2b99c04d8359a8a2098d1217f3c7475547fa0cf (patch) | |
tree | f6bdd3568f0700dfc05e4c8c52e431187e6ee436 | |
parent | f764bcffed69d8c62625dc4b6c1a6af21bd6dbc2 (diff) |
sh: remove assembly code from NPTL
23 files changed, 293 insertions, 5927 deletions
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/Makefile b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/Makefile deleted file mode 100644 index 43a6fad84..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -# Makefile for uClibc NPTL -# -# Copyright (C) 2005 Steven J. Hill <sjhill@uclibc.org> -# -# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. -# - -top_srcdir=../../../../../../../ -top_builddir=../../../../../../../ -all: objs -include $(top_builddir)Rules.mak -include Makefile.arch -include $(top_srcdir)Makerules diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/Makefile.arch b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/Makefile.arch index e3b2f7c4e..77ac2868f 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/Makefile.arch +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/Makefile.arch @@ -5,13 +5,7 @@ # Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. # -libpthread_linux_arch_SSRC = pthread_once.S pthread_rwlock_wrlock.S \ - pthread_rwlock_rdlock.S pthread_rwlock_unlock.S \ - lowlevellock.S lowlevelrobustlock.S pthread_barrier_wait.S \ - pthread_cond_broadcast.S pthread_cond_signal.S \ - pthread_rwlock_timedwrlock.S pthread_rwlock_timedrdlock.S \ - sem_post.S sem_timedwait.S sem_trywait.S sem_wait.S - +libpthread_linux_arch_CSRC = pthread_once.c libc_linux_arch_CSRC = fork.c ASFLAGS += -DUSE___THREAD diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/lowlevel-atomic.h b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/lowlevel-atomic.h deleted file mode 100644 index 939fb0cb6..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/lowlevel-atomic.h +++ /dev/null @@ -1,80 +0,0 @@ -/* Copyright (C) 2003, 2004, 2008 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ - -#ifdef __ASSEMBLER__ - -#define _IMP1 #1 -#define _IMM1 #-1 -#define _IMM4 #-4 -#define _IMM6 #-6 -#define _IMM8 #-8 - -#define INC(mem, reg) \ - .align 2; \ - mova 99f, r0; \ - mov r15, r1; \ - mov _IMM6, r15; \ -98: mov.l mem, reg; \ - add _IMP1, reg; \ - mov.l reg, mem; \ -99: mov r1, r15 - -#define DEC(mem, reg) \ - .align 2; \ - mova 99f, r0; \ - mov r15, r1; \ - mov _IMM6, r15; \ -98: mov.l mem, reg; \ - add _IMM1, reg; \ - mov.l reg, mem; \ -99: mov r1, r15 - -#define XADD(reg, mem, old, tmp) \ - .align 2; \ - mova 99f, r0; \ - nop; \ - mov r15, r1; \ - mov _IMM8, r15; \ -98: mov.l mem, old; \ - mov reg, tmp; \ - add old, tmp; \ - mov.l tmp, mem; \ -99: mov r1, r15 - -#define XCHG(reg, mem, old) \ - .align 2; \ - mova 99f, r0; \ - nop; \ - mov r15, r1; \ - mov _IMM4, r15; \ -98: mov.l mem, old; \ - mov.l reg, mem; \ -99: mov r1, r15 - -#define CMPXCHG(reg, mem, new, old) \ - .align 2; \ - mova 99f, r0; \ - nop; \ - mov r15, r1; \ - mov _IMM8, r15; \ -98: mov.l mem, old; \ - cmp/eq old, reg; \ - bf 99f; \ - mov.l new, mem; \ -99: mov r1, r15 - -#endif /* __ASSEMBLER__ */ diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S deleted file mode 100644 index bac9dd4f2..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S +++ /dev/null @@ -1,539 +0,0 @@ -/* Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009 - Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ - -#include <sysdep.h> -#include <pthread-errnos.h> -#include <bits/kernel-features.h> -#include <lowlevellock.h> -#include <tcb-offsets.h> -#include "lowlevel-atomic.h" - - .text - -#ifdef __ASSUME_PRIVATE_FUTEX -# define LOAD_PRIVATE_FUTEX_WAIT(reg,tmp,tmp2) \ - mov #(FUTEX_WAIT | FUTEX_PRIVATE_FLAG), reg; \ - extu.b reg, reg -# define LOAD_PRIVATE_FUTEX_WAKE(reg,tmp,tmp2) \ - mov #(FUTEX_WAKE | FUTEX_PRIVATE_FLAG), reg; \ - extu.b reg, reg -# define LOAD_FUTEX_WAIT(reg,tmp,tmp2) \ - mov #(FUTEX_WAIT | FUTEX_PRIVATE_FLAG), tmp; \ - extu.b tmp, tmp; \ - xor tmp, reg -# define LOAD_FUTEX_WAIT_ABS(reg,tmp,tmp2) \ - mov #(FUTEX_WAIT_BITSET | FUTEX_PRIVATE_FLAG), tmp; \ - extu.b tmp, tmp; \ - mov #(FUTEX_CLOCK_REALTIME >> 8), tmp2; \ - swap.b tmp2, tmp2; \ - or tmp2, tmp; \ - xor tmp, reg -# define LOAD_FUTEX_WAKE(reg,tmp,tmp2) \ - mov #(FUTEX_WAKE | FUTEX_PRIVATE_FLAG), tmp; \ - extu.b tmp, tmp; \ - xor tmp, reg -#else -# if FUTEX_WAIT == 0 -# define LOAD_PRIVATE_FUTEX_WAIT(reg,tmp,tmp2) \ - stc gbr, tmp ; \ - mov.w 99f, reg ; \ - add reg, tmp ; \ - bra 98f ; \ - mov.l @tmp, reg ; \ -99: .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE ; \ -98: -# else -# define LOAD_PRIVATE_FUTEX_WAIT(reg,tmp,tmp2) \ - stc gbr, tmp ; \ - mov.w 99f, reg ; \ - add reg, tmp ; \ - mov.l @tmp, reg ; \ - bra 98f ; \ - mov #FUTEX_WAIT, tmp ; \ -99: .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE ; \ -98: or tmp, reg -# endif -# define LOAD_PRIVATE_FUTEX_WAKE(reg,tmp,tmp2) \ - stc gbr, tmp ; \ - mov.w 99f, reg ; \ - add reg, tmp ; \ - mov.l @tmp, reg ; \ - bra 98f ; \ - mov #FUTEX_WAKE, tmp ; \ -99: .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE ; \ -98: or tmp, reg -# if FUTEX_WAIT == 0 -# define LOAD_FUTEX_WAIT(reg,tmp,tmp2) \ - stc gbr, tmp ; \ - mov.w 99f, tmp2 ; \ - add tmp2, tmp ; \ - mov.l @tmp, tmp2 ; \ - bra 98f ; \ - mov #FUTEX_PRIVATE_FLAG, tmp ; \ -99: .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE ; \ -98: extu.b tmp, tmp ; \ - xor tmp, reg ; \ - and tmp2, reg -# else -# define LOAD_FUTEX_WAIT(reg,tmp,tmp2) \ - stc gbr, tmp ; \ - mov.w 99f, tmp2 ; \ - add tmp2, tmp ; \ - mov.l @tmp, tmp2 ; \ - bra 98f ; \ - mov #FUTEX_PRIVATE_FLAG, tmp ; \ -99: .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE ; \ -98: extu.b tmp, tmp ; \ - xor tmp, reg ; \ - and tmp2, reg ; \ - mov #FUTEX_WAIT, tmp ; \ - or tmp, reg -# endif -# define LOAD_FUTEX_WAIT_ABS(reg,tmp,tmp2) \ - stc gbr, tmp ; \ - mov.w 99f, tmp2 ; \ - add tmp2, tmp ; \ - mov.l @tmp, tmp2 ; \ - bra 98f ; \ - mov #FUTEX_PRIVATE_FLAG, tmp ; \ -99: .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE ; \ -98: extu.b tmp, tmp ; \ - xor tmp, reg ; \ - and tmp2, reg ; \ - mov #FUTEX_WAIT_BITSET, tmp ; \ - mov #(FUTEX_CLOCK_REALTIME >> 8), tmp2; \ - swap.b tmp2, tmp2; \ - or tmp2, tmp; \ - or tmp, reg -# define LOAD_FUTEX_WAKE(reg,tmp,tmp2) \ - stc gbr, tmp ; \ - mov.w 99f, tmp2 ; \ - add tmp2, tmp ; \ - mov.l @tmp, tmp2 ; \ - bra 98f ; \ - mov #FUTEX_PRIVATE_FLAG, tmp ; \ -99: .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE ; \ -98: extu.b tmp, tmp ; \ - xor tmp, reg ; \ - and tmp2, reg ; \ - mov #FUTEX_WAKE, tmp ; \ - or tmp, reg -#endif - - .globl __lll_lock_wait_private - .type __lll_lock_wait_private,@function - .hidden __lll_lock_wait_private - .align 5 - cfi_startproc -__lll_lock_wait_private: - mov.l r8, @-r15 - cfi_adjust_cfa_offset(4) - cfi_rel_offset (r8, 0) - mov r4, r6 - mov r5, r8 - mov #0, r7 /* No timeout. */ - LOAD_PRIVATE_FUTEX_WAIT (r5, r0, r1) - - mov #2, r4 - cmp/eq r4, r6 - bf 2f - -1: - mov r8, r4 - mov #SYS_futex, r3 - extu.b r3, r3 - trapa #0x14 - SYSCALL_INST_PAD - -2: - mov #2, r6 - XCHG (r6, @r8, r2) - tst r2, r2 - bf 1b - - mov.l @r15+, r8 - rts - mov r2, r0 - cfi_endproc - .size __lll_lock_wait_private,.-__lll_lock_wait_private - -#ifdef NOT_IN_libc - .globl __lll_lock_wait - .type __lll_lock_wait,@function - .hidden __lll_lock_wait - .align 5 - cfi_startproc -__lll_lock_wait: - mov.l r9, @-r15 - cfi_adjust_cfa_offset(4) - cfi_rel_offset (r9, 0) - mov.l r8, @-r15 - cfi_adjust_cfa_offset(4) - cfi_rel_offset (r8, 0) - mov r6, r9 - mov r4, r6 - mov r5, r8 - mov #0, r7 /* No timeout. */ - mov r9, r5 - LOAD_FUTEX_WAIT (r5, r0, r1) - - mov #2, r4 - cmp/eq r4, r6 - bf 2f - -1: - mov r8, r4 - mov #SYS_futex, r3 - extu.b r3, r3 - trapa #0x14 - SYSCALL_INST_PAD - -2: - mov #2, r6 - XCHG (r6, @r8, r2) - tst r2, r2 - bf 1b - - mov.l @r15+, r8 - mov.l @r15+, r9 - ret - mov r2, r0 - cfi_endproc - .size __lll_lock_wait,.-__lll_lock_wait - - /* r5 (r8): futex - r7 (r11): flags - r6 (r9): timeout - r4 (r10): futex value - */ - .globl __lll_timedlock_wait - .type __lll_timedlock_wait,@function - .hidden __lll_timedlock_wait - .align 5 - cfi_startproc -__lll_timedlock_wait: - mov.l r12, @-r15 - cfi_adjust_cfa_offset(4) - cfi_rel_offset (r12, 0) - -# ifndef __ASSUME_FUTEX_CLOCK_REALTIME - mov.l .Lhave, r1 -# ifdef __PIC__ - mova .Lgot, r0 - mov.l .Lgot, r12 - add r0, r12 - add r12, r1 -# endif - mov.l @r1, r0 - tst r0, r0 - bt .Lreltmo -# endif - - mov r4, r2 - mov r5, r4 - mov r7, r5 - mov r6, r7 - LOAD_FUTEX_WAIT_ABS (r5, r0, r1) - - mov #2, r6 - cmp/eq r6, r2 - bf/s 2f - mov r6, r2 - -1: - mov #2, r6 - mov #-1, r1 - mov #SYS_futex, r3 - extu.b r3, r3 - trapa #0x16 - SYSCALL_INST_PAD - mov r0, r6 - -2: - XCHG (r2, @r4, r3) /* NB: lock is implied */ - - tst r3, r3 - bt/s 3f - mov r6, r0 - - cmp/eq #-ETIMEDOUT, r0 - bt 4f - cmp/eq #-EINVAL, r0 - bf 1b -4: - neg r0, r3 -3: - mov r3, r0 - rts - mov.l @r15+, r12 - - .align 2 -# ifndef __ASSUME_FUTEX_CLOCK_REALTIME -# ifdef __PIC__ -.Lgot: - .long _GLOBAL_OFFSET_TABLE_ -.Lhave: - .long __have_futex_clock_realtime@GOTOFF -# else -.Lhave: - .long __have_futex_clock_realtime -# endif - -.Lreltmo: - /* Check for a valid timeout value. */ - mov.l @(4,r6), r1 - mov.l .L1g, r0 - cmp/hs r0, r1 - bt 3f - - mov.l r11, @-r15 - cfi_adjust_cfa_offset(4) - cfi_rel_offset (r11, 0) - mov.l r10, @-r15 - cfi_adjust_cfa_offset(4) - cfi_rel_offset (r10, 0) - mov.l r9, @-r15 - cfi_adjust_cfa_offset(4) - cfi_rel_offset (r9, 0) - mov.l r8, @-r15 - cfi_adjust_cfa_offset(4) - cfi_rel_offset (r8, 0) - mov r7, r11 - mov r4, r10 - mov r6, r9 - mov r5, r8 - - /* Stack frame for the timespec and timeval structs. */ - add #-8, r15 - cfi_adjust_cfa_offset(8) - - mov #2, r2 - XCHG (r2, @r8, r3) - - tst r3, r3 - bt 6f - -1: - /* Get current time. */ - mov r15, r4 - mov #0, r5 - mov #__NR_gettimeofday, r3 - trapa #0x12 - SYSCALL_INST_PAD - - /* Compute relative timeout. */ - mov.l @(4,r15), r0 - mov.w .L1k, r1 - dmulu.l r0, r1 /* Micro seconds to nano seconds. */ - mov.l @r9, r2 - mov.l @(4,r9), r3 - mov.l @r15, r0 - sts macl, r1 - sub r0, r2 - clrt - subc r1, r3 - bf 4f - mov.l .L1g, r1 - add r1, r3 - add #-1, r2 -4: - cmp/pz r2 - bf 2f /* Time is already up. */ - - mov.l r2, @r15 /* Store relative timeout. */ - mov.l r3, @(4,r15) - - mov r8, r4 - mov r11, r5 - LOAD_FUTEX_WAIT (r5, r0, r1) - mov r10, r6 - mov r15, r7 - mov #SYS_futex, r3 - extu.b r3, r3 - trapa #0x14 - SYSCALL_INST_PAD - mov r0, r5 - - mov #2, r2 - XCHG (r2, @r8, r3) - - tst r3, r3 - bt/s 6f - mov #-ETIMEDOUT, r1 - cmp/eq r5, r1 - bf 1b - -2: mov #ETIMEDOUT, r3 - -6: - mov r3, r0 - add #8, r15 - mov.l @r15+, r8 - mov.l @r15+, r9 - mov.l @r15+, r10 - mov.l @r15+, r11 - rts - mov.l @r15+, r12 - -3: - mov.l @r15+, r12 - rts - mov #EINVAL, r0 -# endif - cfi_endproc - -.L1k: - .word 1000 - .align 2 -.L1g: - .long 1000000000 - - .size __lll_timedlock_wait,.-__lll_timedlock_wait -#endif - - .globl __lll_unlock_wake_private - .type __lll_unlock_wake_private,@function - .hidden __lll_unlock_wake_private - .align 5 - cfi_startproc -__lll_unlock_wake_private: - LOAD_PRIVATE_FUTEX_WAKE (r5, r0, r1) - mov #1, r6 /* Wake one thread. */ - mov #0, r7 - mov.l r7, @r4 /* Stores 0. */ - mov #SYS_futex, r3 - extu.b r3, r3 - trapa #0x14 - SYSCALL_INST_PAD - rts - nop - cfi_endproc - .size __lll_unlock_wake_private,.-__lll_unlock_wake_private - -#ifdef NOT_IN_libc - .globl __lll_unlock_wake - .type __lll_unlock_wake,@function - .hidden __lll_unlock_wake - .align 5 - cfi_startproc -__lll_unlock_wake: - LOAD_FUTEX_WAKE (r5, r0, r1) - mov #1, r6 /* Wake one thread. */ - mov #0, r7 - mov.l r7, @r4 /* Stores 0. */ - mov #SYS_futex, r3 - extu.b r3, r3 - trapa #0x14 - SYSCALL_INST_PAD - rts - nop - cfi_endproc - .size __lll_unlock_wake,.-__lll_unlock_wake - - .globl __lll_timedwait_tid - .type __lll_timedwait_tid,@function - .hidden __lll_timedwait_tid - .align 5 - cfi_startproc -__lll_timedwait_tid: - mov.l r9, @-r15 - cfi_adjust_cfa_offset(4) - cfi_rel_offset (r9, 0) - mov.l r8, @-r15 - cfi_adjust_cfa_offset(4) - cfi_rel_offset (r8, 0) - mov r4, r8 - mov r5, r9 - - /* Stack frame for the timespec and timeval structs. */ - add #-8, r15 - cfi_adjust_cfa_offset(8) - -2: - /* Get current time. */ - mov r15, r4 - mov #0, r5 - mov #__NR_gettimeofday, r3 - trapa #0x12 - SYSCALL_INST_PAD - - /* Compute relative timeout. */ - mov.l @(4,r15), r0 - mov.w .L1k2, r1 - dmulu.l r0, r1 /* Micro seconds to nano seconds. */ - mov.l @r9, r2 - mov.l @(4,r9), r3 - mov.l @r15, r0 - sts macl, r1 - sub r0, r2 - clrt - subc r1, r3 - bf 5f - mov.l .L1g2, r1 - add r1, r3 - add #-1, r2 -5: - cmp/pz r2 - bf 6f /* Time is already up. */ - - mov.l r2, @r15 /* Store relative timeout. */ - mov.l r3, @(4,r15) - - mov.l @r8, r2 - tst r2, r2 - bt 4f - - mov r8, r4 - /* XXX The kernel so far uses global futex for the wakeup at - all times. */ - mov #0, r5 - extu.b r5, r5 - mov r2, r6 - mov r15, r7 - mov #SYS_futex, r3 - extu.b r3, r3 - trapa #0x14 - SYSCALL_INST_PAD - - mov.l @r8, r2 - tst r2, r2 - bf 1f -4: - mov #0, r0 -3: - add #8, r15 - mov.l @r15+, r8 - rts - mov.l @r15+, r9 -1: - /* Check whether the time expired. */ - mov #-ETIMEDOUT, r1 - cmp/eq r0, r1 - bf 2b -6: - bra 3b - mov #ETIMEDOUT, r0 - cfi_endproc - -.L1k2: - .word 1000 - .align 2 -.L1g2: - .long 1000000000 - .size __lll_timedwait_tid,.-__lll_timedwait_tid -#endif diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h index a9652bbb1..abe6e9c37 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h @@ -1,5 +1,4 @@ -/* Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009 - Free Software Foundation, Inc. +/* Copyright (C) 2005-2013 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -9,27 +8,29 @@ The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see + License along with the GNU C Library. If not, see <http://www.gnu.org/licenses/>. */ #ifndef _LOWLEVELLOCK_H #define _LOWLEVELLOCK_H 1 -#ifndef __ASSEMBLER__ #include <time.h> #include <sys/param.h> #include <bits/pthreadtypes.h> +#include <atomic.h> +#include <sysdep.h> #include <bits/kernel-features.h> -#endif #define FUTEX_WAIT 0 #define FUTEX_WAKE 1 +#define FUTEX_REQUEUE 3 #define FUTEX_CMP_REQUEUE 4 #define FUTEX_WAKE_OP 5 +#define FUTEX_OP_CLEAR_WAKE_IF_GT_ONE ((4 << 24) | 1) #define FUTEX_LOCK_PI 6 #define FUTEX_UNLOCK_PI 7 #define FUTEX_TRYLOCK_PI 8 @@ -40,13 +41,11 @@ #define FUTEX_BITSET_MATCH_ANY 0xffffffff -#define FUTEX_OP_CLEAR_WAKE_IF_GT_ONE ((4 << 24) | 1) - /* Values for 'private' parameter of locking macros. Yes, the definition seems to be backwards. But it is not. The bit will be reversed before passing to the system call. */ -#define LLL_PRIVATE 0 -#define LLL_SHARED FUTEX_PRIVATE_FLAG +#define LLL_PRIVATE 0 +#define LLL_SHARED FUTEX_PRIVATE_FLAG #if !defined NOT_IN_libc || defined IS_IN_rtld @@ -73,347 +72,222 @@ # endif #endif -#ifndef __ASSEMBLER__ -/* Initializer for compatibility lock. */ -#define LLL_LOCK_INITIALIZER (0) -#define LLL_LOCK_INITIALIZER_LOCKED (1) -#define LLL_LOCK_INITIALIZER_WAITERS (2) - -extern int __lll_lock_wait_private (int val, int *__futex) - attribute_hidden; -extern int __lll_lock_wait (int val, int *__futex, int private) - attribute_hidden; -extern int __lll_timedlock_wait (int val, int *__futex, - const struct timespec *abstime, int private) - attribute_hidden; -extern int __lll_robust_lock_wait (int val, int *__futex, int private) - attribute_hidden; -extern int __lll_robust_timedlock_wait (int val, int *__futex, - const struct timespec *abstime, - int private) - attribute_hidden; -extern int __lll_unlock_wake_private (int *__futex) attribute_hidden; -extern int __lll_unlock_wake (int *__futex, int private) attribute_hidden; - -#define lll_trylock(futex) \ - ({ unsigned char __ret; \ - __asm__ __volatile__ ("\ - .align 2\n\ - mova 1f,r0\n\ - nop\n\ - mov r15,r1\n\ - mov #-8,r15\n\ - 0: mov.l @%1,r2\n\ - cmp/eq r2,%3\n\ - bf 1f\n\ - mov.l %2,@%1\n\ - 1: mov r1,r15\n\ - mov #-1,%0\n\ - negc %0,%0"\ - : "=r" (__ret) \ - : "r" (&(futex)), \ - "r" (LLL_LOCK_INITIALIZER_LOCKED), \ - "r" (LLL_LOCK_INITIALIZER) \ - : "r0", "r1", "r2", "t", "memory"); \ - __ret; }) - -#define lll_robust_trylock(futex, id) \ - ({ unsigned char __ret; \ - __asm__ __volatile__ ("\ - .align 2\n\ - mova 1f,r0\n\ - nop\n\ - mov r15,r1\n\ - mov #-8,r15\n\ - 0: mov.l @%1,r2\n\ - cmp/eq r2,%3\n\ - bf 1f\n\ - mov.l %2,@%1\n\ - 1: mov r1,r15\n\ - mov #-1,%0\n\ - negc %0,%0"\ - : "=r" (__ret) \ - : "r" (&(futex)), \ - "r" (id), \ - "r" (LLL_LOCK_INITIALIZER) \ - : "r0", "r1", "r2", "t", "memory"); \ - __ret; }) - -#define lll_cond_trylock(futex) \ - ({ unsigned char __ret; \ - __asm__ __volatile__ ("\ - .align 2\n\ - mova 1f,r0\n\ - nop\n\ - mov r15,r1\n\ - mov #-8,r15\n\ - 0: mov.l @%1,r2\n\ - cmp/eq r2,%3\n\ - bf 1f\n\ - mov.l %2,@%1\n\ - 1: mov r1,r15\n\ - mov #-1,%0\n\ - negc %0,%0"\ - : "=r" (__ret) \ - : "r" (&(futex)), \ - "r" (LLL_LOCK_INITIALIZER_WAITERS), \ - "r" (LLL_LOCK_INITIALIZER) \ - : "r0", "r1", "r2", "t", "memory"); \ - __ret; }) - -#define lll_lock(futex, private) \ - (void) ({ int __ret, *__futex = &(futex); \ - __asm__ __volatile__ ("\ - .align 2\n\ - mova 1f,r0\n\ - nop\n\ - mov r15,r1\n\ - mov #-8,r15\n\ - 0: mov.l @%2,%0\n\ - tst %0,%0\n\ - bf 1f\n\ - mov.l %1,@%2\n\ - 1: mov r1,r15"\ - : "=&r" (__ret) : "r" (1), "r" (__futex) \ - : "r0", "r1", "t", "memory"); \ - if (__ret) \ - { \ - if (__builtin_constant_p (private) \ - && (private) == LLL_PRIVATE) \ - __lll_lock_wait_private (__ret, __futex); \ - else \ - __lll_lock_wait (__ret, __futex, (private)); \ - } \ - }) +#define lll_futex_wait(futexp, val, private) \ + lll_futex_timed_wait(futexp, val, NULL, private) + +#define lll_futex_timed_wait(futexp, val, timespec, private) \ + ({ \ + INTERNAL_SYSCALL_DECL (__err); \ + long int __ret; \ + __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp), \ + __lll_private_flag (FUTEX_WAIT, private), \ + (val), (timespec)); \ + __ret; \ + }) + +#define lll_futex_timed_wait_bitset(futexp, val, timespec, clockbit, private) \ + ({ \ + INTERNAL_SYSCALL_DECL (__err); \ + long int __ret; \ + int __op = FUTEX_WAIT_BITSET | clockbit; \ + __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp), \ + __lll_private_flag (__op, private), \ + (val), (timespec), NULL /* Unused. */, \ + FUTEX_BITSET_MATCH_ANY); \ + __ret; \ + }) + +#define lll_futex_wake(futexp, nr, private) \ + ({ \ + INTERNAL_SYSCALL_DECL (__err); \ + long int __ret; \ + __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp), \ + __lll_private_flag (FUTEX_WAKE, private), \ + (nr), 0); \ + __ret; \ + }) + +#define lll_robust_dead(futexv, private) \ + do \ + { \ + int *__futexp = &(futexv); \ + atomic_or (__futexp, FUTEX_OWNER_DIED); \ + lll_futex_wake (__futexp, 1, private); \ + } \ + while (0) + +/* Returns non-zero if error happened, zero if success. */ +#define lll_futex_requeue(futexp, nr_wake, nr_move, mutex, val, private) \ + ({ \ + INTERNAL_SYSCALL_DECL (__err); \ + long int __ret; \ + __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp), \ + __lll_private_flag (FUTEX_CMP_REQUEUE, private),\ + (nr_wake), (nr_move), (mutex), (val)); \ + INTERNAL_SYSCALL_ERROR_P (__ret, __err); \ + }) + + +/* Returns non-zero if error happened, zero if success. */ +#define lll_futex_wake_unlock(futexp, nr_wake, nr_wake2, futexp2, private) \ + ({ \ + INTERNAL_SYSCALL_DECL (__err); \ + long int __ret; \ + __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp), \ + __lll_private_flag (FUTEX_WAKE_OP, private), \ + (nr_wake), (nr_wake2), (futexp2), \ + FUTEX_OP_CLEAR_WAKE_IF_GT_ONE); \ + INTERNAL_SYSCALL_ERROR_P (__ret, __err); \ + }) + + +#define lll_trylock(lock) \ + atomic_compare_and_exchange_val_acq(&(lock), 1, 0) + +#define lll_cond_trylock(lock) \ + atomic_compare_and_exchange_val_acq(&(lock), 2, 0) + +#define __lll_robust_trylock(futex, id) \ + (atomic_compare_and_exchange_val_acq (futex, id, 0) != 0) +#define lll_robust_trylock(lock, id) \ + __lll_robust_trylock (&(lock), id) + +extern void __lll_lock_wait_private (int *futex) attribute_hidden; +extern void __lll_lock_wait (int *futex, int private) attribute_hidden; +extern int __lll_robust_lock_wait (int *futex, int private) attribute_hidden; + +#define __lll_lock(futex, private) \ + ((void) ({ \ + int *__futex = (futex); \ + if (__builtin_expect (atomic_compare_and_exchange_val_acq (__futex, \ + 1, 0), 0)) \ + { \ + if (__builtin_constant_p (private) && (private) == LLL_PRIVATE) \ + __lll_lock_wait_private (__futex); \ + else \ + __lll_lock_wait (__futex, private); \ + } \ + })) +#define lll_lock(futex, private) __lll_lock (&(futex), private) + +#define __lll_robust_lock(futex, id, private) \ + ({ \ + int *__futex = (futex); \ + int __val = 0; \ + \ + if (__builtin_expect (atomic_compare_and_exchange_bool_acq (__futex, id, \ + 0), 0)) \ + __val = __lll_robust_lock_wait (__futex, private); \ + __val; \ + }) #define lll_robust_lock(futex, id, private) \ - ({ int __ret, *__futex = &(futex); \ - __asm__ __volatile__ ("\ - .align 2\n\ - mova 1f,r0\n\ - nop\n\ - mov r15,r1\n\ - mov #-8,r15\n\ - 0: mov.l @%2,%0\n\ - tst %0,%0\n\ - bf 1f\n\ - mov.l %1,@%2\n\ - 1: mov r1,r15"\ - : "=&r" (__ret) : "r" (id), "r" (__futex) \ - : "r0", "r1", "t", "memory"); \ - if (__ret) \ - __ret = __lll_robust_lock_wait (__ret, __futex, private); \ - __ret; }) - -/* Special version of lll_mutex_lock which causes the unlock function to - always wakeup waiters. */ -#define lll_cond_lock(futex, private) \ - (void) ({ int __ret, *__futex = &(futex); \ - __asm__ __volatile__ ("\ - .align 2\n\ - mova 1f,r0\n\ - nop\n\ - mov r15,r1\n\ - mov #-8,r15\n\ - 0: mov.l @%2,%0\n\ - tst %0,%0\n\ - bf 1f\n\ - mov.l %1,@%2\n\ - 1: mov r1,r15"\ - : "=&r" (__ret) : "r" (2), "r" (__futex) \ - : "r0", "r1", "t", "memory"); \ - if (__ret) \ - __lll_lock_wait (__ret, __futex, private); }) + __lll_robust_lock (&(futex), id, private) + + +#define __lll_cond_lock(futex, private) \ + ((void) ({ \ + int *__futex = (futex); \ + if (__builtin_expect (atomic_exchange_acq (__futex, 2), 0)) \ + __lll_lock_wait (__futex, private); \ + })) +#define lll_cond_lock(futex, p |