diff options
| author | Max Filippov <jcmvbkbc@gmail.com> | 2020-08-08 23:28:17 -0700 | 
|---|---|---|
| committer | Waldemar Brodkorb <wbx@openadk.org> | 2020-08-11 13:35:02 +0200 | 
| commit | fc48f4fb0506b2ea6ef3bb33037be3a4da2874bc (patch) | |
| tree | aa83e91570361d19ca569ea68d279b98b69ec3b5 /libpthread/linuxthreads/sysdeps | |
| parent | c2e5177b97825211565150b4f9a7f253e0458619 (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/linuxthreads/sysdeps')
| -rw-r--r-- | libpthread/linuxthreads/sysdeps/xtensa/pt-machine.h | 56 | 
1 files changed, 56 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) | 
