Fix ODR violations in code using <ext/atomicity.h>

Because the inline versions of __exchange_and_add and __atomic_add are
also marked static, they cannot be used from templates or other inline
functions without ODR violations. This change gives them external
linkage, but adds the always_inline attribute.

    	* include/ext/atomicity.h [_GLIBCXX_ATOMIC_BUILTINS] (__atomic_add)
    	(__exchange_and_add): Replace static specifier with always_inline
    	attribute.
    	(__exchange_and_add_single, __atomic_add_single): Likewise.
    	(__exchange_and_add_dispatch, __atomic_add_dispatch): Likewise. Also
    	combine !__gthread_active_p() and !__GTHREADS branches.

From-SVN: r273144
This commit is contained in:
Jonathan Wakely 2019-07-05 17:10:47 +01:00 committed by Jonathan Wakely
parent 6e158c5fd5
commit 0dc7adb037
2 changed files with 23 additions and 18 deletions

View File

@ -1,3 +1,12 @@
2019-07-05 Jonathan Wakely <jwakely@redhat.com>
* include/ext/atomicity.h [_GLIBCXX_ATOMIC_BUILTINS] (__atomic_add)
(__exchange_and_add): Replace static specifier with always_inline
attribute.
(__exchange_and_add_single, __atomic_add_single): Likewise.
(__exchange_and_add_dispatch, __atomic_add_dispatch): Likewise. Also
combine !__gthread_active_p() and !__GTHREADS branches.
2019-07-03 Jonathan Wakely <jwakely@redhat.com>
PR libstdc++/91067

View File

@ -44,24 +44,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// __exchange_and_add_dispatch
// __atomic_add_dispatch
#ifdef _GLIBCXX_ATOMIC_BUILTINS
static inline _Atomic_word
inline _Atomic_word
__attribute__((__always_inline__))
__exchange_and_add(volatile _Atomic_word* __mem, int __val)
{ return __atomic_fetch_add(__mem, __val, __ATOMIC_ACQ_REL); }
static inline void
inline void
__attribute__((__always_inline__))
__atomic_add(volatile _Atomic_word* __mem, int __val)
{ __atomic_fetch_add(__mem, __val, __ATOMIC_ACQ_REL); }
#else
_Atomic_word
__attribute__ ((__unused__))
__exchange_and_add(volatile _Atomic_word*, int) throw ();
void
__attribute__ ((__unused__))
__atomic_add(volatile _Atomic_word*, int) throw ();
#endif
static inline _Atomic_word
inline _Atomic_word
__attribute__((__always_inline__))
__exchange_and_add_single(_Atomic_word* __mem, int __val)
{
_Atomic_word __result = *__mem;
@ -69,36 +70,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return __result;
}
static inline void
inline void
__attribute__((__always_inline__))
__atomic_add_single(_Atomic_word* __mem, int __val)
{ *__mem += __val; }
static inline _Atomic_word
__attribute__ ((__unused__))
inline _Atomic_word
__attribute__ ((__always_inline__))
__exchange_and_add_dispatch(_Atomic_word* __mem, int __val)
{
#ifdef __GTHREADS
if (__gthread_active_p())
return __exchange_and_add(__mem, __val);
else
return __exchange_and_add_single(__mem, __val);
#else
return __exchange_and_add_single(__mem, __val);
#endif
return __exchange_and_add_single(__mem, __val);
}
static inline void
__attribute__ ((__unused__))
inline void
__attribute__ ((__always_inline__))
__atomic_add_dispatch(_Atomic_word* __mem, int __val)
{
#ifdef __GTHREADS
if (__gthread_active_p())
__atomic_add(__mem, __val);
else
__atomic_add_single(__mem, __val);
#else
__atomic_add_single(__mem, __val);
#endif
__atomic_add_single(__mem, __val);
}
_GLIBCXX_END_NAMESPACE_VERSION