This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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




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.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]