summaryrefslogtreecommitdiff
path: root/libpthread
diff options
context:
space:
mode:
authorMax Filippov <jcmvbkbc@gmail.com>2020-08-08 23:28:17 -0700
committerWaldemar Brodkorb <wbx@openadk.org>2020-08-11 13:35:02 +0200
commitfc48f4fb0506b2ea6ef3bb33037be3a4da2874bc (patch)
treeaa83e91570361d19ca569ea68d279b98b69ec3b5 /libpthread
parentc2e5177b97825211565150b4f9a7f253e0458619 (diff)
xtensa: add exclusive access support
Add XCHAL definitions for S32C1I and EXCLUSIVE options to xtensa-config.h, include it in places that implement atomic operations and add implementations with exclusive access option opcodes. Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Diffstat (limited to 'libpthread')
-rw-r--r--libpthread/linuxthreads/sysdeps/xtensa/pt-machine.h56
-rw-r--r--libpthread/nptl/sysdeps/xtensa/pthread_spin_lock.S16
-rw-r--r--libpthread/nptl/sysdeps/xtensa/pthread_spin_trylock.S17
3 files changed, 89 insertions, 0 deletions
diff --git a/libpthread/linuxthreads/sysdeps/xtensa/pt-machine.h b/libpthread/linuxthreads/sysdeps/xtensa/pt-machine.h
index 82d9b540c..0b7f58b63 100644
--- a/libpthread/linuxthreads/sysdeps/xtensa/pt-machine.h
+++ b/libpthread/linuxthreads/sysdeps/xtensa/pt-machine.h
@@ -21,6 +21,7 @@
#ifndef _PT_MACHINE_H
#define _PT_MACHINE_H 1
+#include <bits/xtensa-config.h>
#include <sys/syscall.h>
#include <asm/unistd.h>
@@ -34,6 +35,55 @@
extern long int testandset (int *spinlock);
extern int __compare_and_swap (long int *p, long int oldval, long int newval);
+#if XCHAL_HAVE_EXCLUSIVE
+
+/* Spinlock implementation; required. */
+PT_EI long int
+testandset (int *spinlock)
+{
+ unsigned long tmp;
+ __asm__ volatile (
+" memw \n"
+"1: l32ex %0, %1 \n"
+" bnez %0, 2f \n"
+" movi %0, 1 \n"
+" s32ex %0, %1 \n"
+" getex %0 \n"
+" beqz %0, 1b \n"
+" movi %0, 0 \n"
+" memw \n"
+"2: \n"
+ : "=&a" (tmp)
+ : "a" (spinlock)
+ : "memory"
+ );
+ return tmp;
+}
+
+PT_EI int
+__compare_and_swap (long int *p, long int oldval, long int newval)
+{
+ unsigned long tmp;
+ unsigned long value;
+ __asm__ volatile (
+" memw \n"
+"1: l32ex %0, %2 \n"
+" bne %0, %4, 2f \n"
+" mov %1, %3 \n"
+" s32ex %1, %2 \n"
+" getex %1 \n"
+" beqz %1, 1b \n"
+" memw \n"
+"2: \n"
+ : "=&a" (tmp), "=&a" (value)
+ : "a" (p), "a" (newval), "a" (oldval)
+ : "memory" );
+
+ return tmp == oldval;
+}
+
+#elif XCHAL_HAVE_S32C1I
+
/* Spinlock implementation; required. */
PT_EI long int
testandset (int *spinlock)
@@ -71,6 +121,12 @@ __compare_and_swap (long int *p, long int oldval, long int newval)
return tmp == oldval;
}
+#else
+
+#error No hardware atomic operations
+
+#endif
+
/* Get some notion of the current stack. Need not be exactly the top
of the stack, just something somewhere in the current frame. */
#define CURRENT_STACK_FRAME __builtin_frame_address (0)
diff --git a/libpthread/nptl/sysdeps/xtensa/pthread_spin_lock.S b/libpthread/nptl/sysdeps/xtensa/pthread_spin_lock.S
index 3386afae9..3faac36da 100644
--- a/libpthread/nptl/sysdeps/xtensa/pthread_spin_lock.S
+++ b/libpthread/nptl/sysdeps/xtensa/pthread_spin_lock.S
@@ -15,16 +15,32 @@
License along with the GNU C Library; see the file COPYING.LIB. If
not, see <http://www.gnu.org/licenses/>.  */
+#include <bits/xtensa-config.h>
#include <sysdep.h>
.text
ENTRY (pthread_spin_lock)
+#if XCHAL_HAVE_EXCLUSIVE
+ memw
+1: l32ex a3, a2
+ bnez a3, 1b
+ movi a3, 1
+ s32ex a3, a2
+ getex a3
+ beqz a3, 1b
+ memw
+#elif XCHAL_HAVE_S32C1I
movi a3, 0
wsr a3, scompare1
movi a3, 1
1: s32c1i a3, a2, 0
bnez a3, 1b
+#else
+
+#error No hardware atomic operations
+
+#endif
movi a2, 0
abi_ret
diff --git a/libpthread/nptl/sysdeps/xtensa/pthread_spin_trylock.S b/libpthread/nptl/sysdeps/xtensa/pthread_spin_trylock.S
index 72b2dda92..0669682ec 100644
--- a/libpthread/nptl/sysdeps/xtensa/pthread_spin_trylock.S
+++ b/libpthread/nptl/sysdeps/xtensa/pthread_spin_trylock.S
@@ -17,15 +17,32 @@
#define _ERRNO_H 1
#include <bits/errno.h>
+#include <bits/xtensa-config.h>
#include <sysdep.h>
.text
ENTRY (pthread_spin_trylock)
+#if XCHAL_HAVE_EXCLUSIVE
+ memw
+ l32ex a3, a2
+ bnez a3, 1f
+ movi a3, 1
+ s32ex a3, a2
+ getex a3
+ addi a3, a3, -1
+ memw
+1:
+#elif XCHAL_HAVE_S32C1I
movi a3, 0
wsr a3, scompare1
movi a3, 1
s32c1i a3, a2, 0
+#else
+
+#error No hardware atomic operations
+
+#endif
movi a2, EBUSY
moveqz a2, a3, a3