On 1 November 2014 10:00, Sergei Poselenov <[email protected]> wrote:
> commit 683a77455f2226419fe688dd2104ef1a391bb3b2
> Author: Sergei Poselenov <[email protected]>
> Date:   Sun Oct 26 14:54:12 2014 +0400
>
>     Implemented testandset() for Cortex-M3

Don't we have some CAS support in libc/sysdeps/linux/arm/bits/atomic.h
that should have been used?

>
>     Signed-off-by: Sergei Poselenov <[email protected]>
>
> diff --git a/extra/Configs/Config.arm b/extra/Configs/Config.arm
> index 0bb2971..5777d3b 100644
> --- a/extra/Configs/Config.arm
> +++ b/extra/Configs/Config.arm
> @@ -36,3 +36,10 @@ config USE_BX
>           Say 'y' to use BX to return from functions on your thumb-aware
>           processor. Say 'y' if you need to use interworking. Say 'n' if not.
>           It is safe to say 'y' even if you're not doing interworking.
> +
> +config USE_LDREXSTREX
> +       bool "Use load-store exclusive ASM ops (not supported in SmartFusion)"
> +       depends on COMPILE_IN_THUMB_MODE
> +       default y
> +       help
> +         Say 'y' to use LDREX/STREX ASM ops.

That sounds rather like you want to have it conditional on something like
__ARM_ARCH_6M__ or __ARM_ARCH >= 6 no?

thanks,

> diff --git a/libpthread/linuxthreads.old/sysdeps/arm/pt-machine.h 
> b/libpthread/linuxthreads.old/sysdeps/arm/pt-machine.h
> index 583eb68..93804ba 100644
> --- a/libpthread/linuxthreads.old/sysdeps/arm/pt-machine.h
> +++ b/libpthread/linuxthreads.old/sysdeps/arm/pt-machine.h
> @@ -22,12 +22,50 @@
>  #ifndef _PT_MACHINE_H
>  #define _PT_MACHINE_H   1
>
> -#include <features.h>
> +#include <sys/syscall.h>
> +#include <unistd.h>
>
>  #ifndef PT_EI
>  # define PT_EI __extern_always_inline
>  #endif
>
> +#if defined(__thumb__)
> +#if defined(__USE_LDREXSTREX__)
> +PT_EI long int ldrex(int *spinlock)
> +{
> +       long int ret;
> +       __asm__ __volatile__(
> +               "ldrex %0, [%1]\n"
> +               : "=r"(ret)
> +               : "r"(spinlock) : "memory");
> +       return ret;
> +}
> +
> +PT_EI long int strex(int val, int *spinlock)
> +{
> +       long int ret;
> +       __asm__ __volatile__(
> +               "strex %0, %1, [%2]\n"
> +               : "=r"(ret)
> +               : "r" (val), "r"(spinlock) : "memory");
> +       return ret;
> +}
> +
> +/* Spinlock implementation; required.  */
> +PT_EI long int
> +testandset (int *spinlock)
> +{
> +  register unsigned int ret;
> +
> +  do {
> +         ret = ldrex(spinlock);
> +  } while (strex(1, spinlock));
> +
> +  return ret;
> +}
> +
> +#else /* __USE_LDREXSTREX__ */
> +
>  /* This will not work on ARM1 or ARM2 because SWP is lacking on those
>     machines.  Unfortunately we have no way to detect this at compile
>     time; let's hope nobody tries to use one.  */
> @@ -37,8 +75,6 @@ PT_EI long int testandset (int *spinlock);
>  PT_EI long int testandset (int *spinlock)
>  {
>    register unsigned int ret;
> -
> -#if defined(__thumb__)
>    void *pc;
>    __asm__ __volatile__(
>         ".align 0\n"
> @@ -51,15 +87,21 @@ PT_EI long int testandset (int *spinlock)
>         "\t.force_thumb"
>         : "=r"(ret), "=r"(pc)
>         : "0"(1), "r"(spinlock));
> -#else
> +  return ret;
> +}
> +#endif
> +#else /* __thumb__ */
> +
> +PT_EI long int testandset (int *spinlock);
> +PT_EI long int testandset (int *spinlock)
> +{
> +  register unsigned int ret;
>    __asm__ __volatile__("swp %0, %1, [%2]"
>                        : "=r"(ret)
>                        : "0"(1), "r"(spinlock));
> -#endif
> -
>    return ret;
>  }
> -
> +#endif
>
>  /* Get some notion of the current stack.  Need not be exactly the top
>     of the stack, just something somewhere in the current frame.  */
>
>
_______________________________________________
uClibc mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/uclibc

Reply via email to