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