libstdc++-v3/config/cpu/m68k/atomicity.h

Sebastian Huber sebastian.huber@embedded-brains.de
Tue Sep 13 06:32:00 GMT 2016



On 09/09/16 15:14, Jonathan Wakely wrote:
> On 09/09/16 10:28 +0200, Sebastian Huber wrote:
>> Hello,
>>
>> for RTEMS there is a special case in:
>>
>> libstdc++-v3/config/cpu/m68k/atomicity.h
>>
>> [...]
>> namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
>> {
>> [...]
>> #elif defined(__rtems__)
>>  // TAS/JBNE is unsafe on systems with strict priority-based scheduling.
>>  // Disable interrupts, which we can do only from supervisor mode.
>>  _Atomic_word
>>  __attribute__ ((__unused__))
>>  __exchange_and_add(volatile _Atomic_word* __mem, int __val) throw ()
>>  {
>>    _Atomic_word __result;
>>    short __level, __tmpsr;
>>    __asm__ __volatile__ ("move%.w %%sr,%0\n\tor%.l %0,%1\n\tmove%.w 
>> %1,%%sr"
>>              : "=d"(__level), "=d"(__tmpsr) : "1"(0x700));
>>
>>    __result = *__mem;
>>    *__mem = __result + __val;
>>    __asm__ __volatile__ ("move%.w %0,%%sr" : : "d"(__level));
>>
>>    return __result;
>>  }
>>
>> #else
>> [...]
>>
>> Since C++14 is the default for GCC 6, would it be possible to use the 
>> standard atomic operations instead? For targets that don't support 
>> the operations in hardware, this would lead to a libatomic dependency.
>
> C++14 isn't relevant, since the std::atomic_* operations only work on
> std::atomic<T> objects, not _Atomic_word objects.
>
> The code could use the same __atomic_* built-ins that are used by
> std::atomic<T>, but they are always available, so C++14 isn't needed
> for that.
>
> As you say, that introduces a dependency on libatomic, so would be a
> decision for the target maintainer to make.

I would like to use the libatomic for RTEMS for libstdc++ on all targets.

The libstdc++ configure script performs this:

[...]
     cat > conftest.$ac_ext << EOF
#line 15391 "configure"
int main()
{
   typedef bool atomic_type;
   atomic_type c1;
   atomic_type c2;
   atomic_type c3(0);
   // N.B. __atomic_fetch_add is not supported for bool.
   __atomic_compare_exchange_n(&c1, &c2, c3, true, __ATOMIC_ACQ_REL,
                   __ATOMIC_RELAXED);
   __atomic_test_and_set(&c1, __ATOMIC_RELAXED);
   __atomic_load_n(&c1, __ATOMIC_RELAXED);

   return 0;
}
EOF

     { $as_echo "$as_me:${as_lineno-$LINENO}: checking for atomic 
builtins for bool" >&5
$as_echo_n "checking for atomic builtins for bool... " >&6; }
     if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: 
\"$ac_compile\""; } >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
       if grep __atomic_ conftest.s >/dev/null 2>&1 ; then
     glibcxx_cv_atomic_bool=no
       else
     glibcxx_cv_atomic_bool=yes
       fi
     fi
[...]

So, it compiles a test using atomic operations. If it finds references 
to external __atomic* functions, then it assumes the atomic operations 
are not supported for this type.

Later we have:

[...]
   # Set atomicity_dir to builtins if all but the long long test above 
passes.
   if test "$glibcxx_cv_atomic_bool" = yes \
      && test "$glibcxx_cv_atomic_short" = yes \
      && test "$glibcxx_cv_atomic_int" = yes; then

$as_echo "#define _GLIBCXX_ATOMIC_BUILTINS 1" >>confdefs.h

     atomicity_dir=cpu/generic/atomicity_builtins
   fi
[...]

So, the fall back is chosen for most m68k multilibs:

/opt/rtems-4.12/lib64/gcc/m68k-rtems4.12/6.2.1/include/c++/m68k-rtems4.12/mcpu32/bits/c++config.h:/* 
#undef _GLIBCXX_ATOMIC_BUILTINS */
/opt/rtems-4.12/lib64/gcc/m68k-rtems4.12/6.2.1/include/c++/m68k-rtems4.12/softfp/bits/c++config.h:#define 
_GLIBCXX_ATOMIC_BUILTINS 1
/opt/rtems-4.12/lib64/gcc/m68k-rtems4.12/6.2.1/include/c++/m68k-rtems4.12/m68040/softfp/bits/c++config.h:#define 
_GLIBCXX_ATOMIC_BUILTINS 1
/opt/rtems-4.12/lib64/gcc/m68k-rtems4.12/6.2.1/include/c++/m68k-rtems4.12/m68040/bits/c++config.h:#define 
_GLIBCXX_ATOMIC_BUILTINS 1
/opt/rtems-4.12/lib64/gcc/m68k-rtems4.12/6.2.1/include/c++/m68k-rtems4.12/m68060/softfp/bits/c++config.h:#define 
_GLIBCXX_ATOMIC_BUILTINS 1
/opt/rtems-4.12/lib64/gcc/m68k-rtems4.12/6.2.1/include/c++/m68k-rtems4.12/m68060/bits/c++config.h:#define 
_GLIBCXX_ATOMIC_BUILTINS 1
/opt/rtems-4.12/lib64/gcc/m68k-rtems4.12/6.2.1/include/c++/m68k-rtems4.12/m5206/bits/c++config.h:/* 
#undef _GLIBCXX_ATOMIC_BUILTINS */
/opt/rtems-4.12/lib64/gcc/m68k-rtems4.12/6.2.1/include/c++/m68k-rtems4.12/m5208/bits/c++config.h:/* 
#undef _GLIBCXX_ATOMIC_BUILTINS */
/opt/rtems-4.12/lib64/gcc/m68k-rtems4.12/6.2.1/include/c++/m68k-rtems4.12/m68000/bits/c++config.h:/* 
#undef _GLIBCXX_ATOMIC_BUILTINS */
/opt/rtems-4.12/lib64/gcc/m68k-rtems4.12/6.2.1/include/c++/m68k-rtems4.12/m5307/bits/c++config.h:/* 
#undef _GLIBCXX_ATOMIC_BUILTINS */
/opt/rtems-4.12/lib64/gcc/m68k-rtems4.12/6.2.1/include/c++/m68k-rtems4.12/m5329/bits/c++config.h:/* 
#undef _GLIBCXX_ATOMIC_BUILTINS */
/opt/rtems-4.12/lib64/gcc/m68k-rtems4.12/6.2.1/include/c++/m68k-rtems4.12/m5407/bits/c++config.h:/* 
#undef _GLIBCXX_ATOMIC_BUILTINS */
/opt/rtems-4.12/lib64/gcc/m68k-rtems4.12/6.2.1/include/c++/m68k-rtems4.12/bits/c++config.h:#define 
_GLIBCXX_ATOMIC_BUILTINS 1
/opt/rtems-4.12/lib64/gcc/m68k-rtems4.12/6.2.1/include/c++/m68k-rtems4.12/m5475/softfp/bits/c++config.h:/* 
#undef _GLIBCXX_ATOMIC_BUILTINS */
/opt/rtems-4.12/lib64/gcc/m68k-rtems4.12/6.2.1/include/c++/m68k-rtems4.12/m5475/bits/c++config.h:/* 
#undef _GLIBCXX_ATOMIC_BUILTINS */

The fall back for the m5475 mulitlib is for example:

atomicity.o:     file format elf32-m68k


Disassembly of section .text._ZN9__gnu_cxx18__exchange_and_addEPVii:

00000000 <__gnu_cxx::__exchange_and_add(int volatile*, int)>:
    0:   4e56 0000       linkw %fp,#0
    4:   71fc 0700       mvzw #1792,%d0
    8:   206e 0008       moveal %fp@(8),%a0
    c:   40c1            movew %sr,%d1
    e:   8081            orl %d1,%d0
   10:   46c0            movew %d0,%sr
   12:   2010            movel %a0@,%d0
   14:   2240            moveal %d0,%a1
   16:   d3ee 000c       addal %fp@(12),%a1
   1a:   2089            movel %a1,%a0@
   1c:   46c1            movew %d1,%sr
   1e:   4e5e            unlk %fp
   20:   4e75            rts

Disassembly of section .text._ZN9__gnu_cxx12__atomic_addEPVii:

00000000 <__gnu_cxx::__atomic_add(int volatile*, int)>:
    0:   4e56 0000       linkw %fp,#0
    4:   71fc 0700       mvzw #1792,%d0
    8:   206e 0008       moveal %fp@(8),%a0
    c:   40c1            movew %sr,%d1
    e:   8081            orl %d1,%d0
   10:   46c0            movew %d0,%sr
   12:   2010            movel %a0@,%d0
   14:   d0ae 000c       addl %fp@(12),%d0
   18:   2080            movel %d0,%a0@
   1a:   46c1            movew %d1,%sr
   1c:   4e5e            unlk %fp
   1e:   4e75            rts

This is the RTEMS special case variant with interrupt disable/enable.

Would it be possible to modify the atomic builtin configure check, so 
that for some targets the builtins are always used, even if calls to 
libatomic are emitted?

-- 
Sebastian Huber, embedded brains GmbH

Address : Dornierstr. 4, D-82178 Puchheim, Germany
Phone   : +49 89 189 47 41-16
Fax     : +49 89 189 47 41-09
E-Mail  : sebastian.huber@embedded-brains.de
PGP     : Public key available on request.

Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.



More information about the Libstdc++ mailing list