[Patch libstdc++] Rewrite cpu/generic/atomic_word.h
Torvald Riegel
triegel@redhat.com
Fri May 22 16:56:00 GMT 2015
On Fri, 2015-05-22 at 12:37 +0100, Ramana Radhakrishnan wrote:
> Hi,
>
> While writing atomic_word.h for the ARM backend to fix PR target/66200
> I
> thought it would make more sense to write it all up with atomic
> primitives instead of providing various fragile bits of inline
> asssembler. Thus this patch came about. I intend to ask for a
> specialized version of this to be applied for the ARM backend in any
> case after testing completes.
>
> If this goes in as a cleanup I expect all the ports to be deleting
> their
> atomic_word.h implementation in the various ports directories and
> I'll
> follow up with patches asking port maintainers to test and apply for
> each of the individual cases if this is deemed to be good enough.
Could you use C++11 atomics right away instead of adapting the wrappers?
I think the more non-C++11 atomic operations/wrappers we can remove the
better.
> diff --git a/libstdc++-v3/config/cpu/generic/atomic_word.h b/libstdc
> ++-v3/config/cpu/generic/atomic_word.h
> index 19038bb..bedce31 100644
> --- a/libstdc++-v3/config/cpu/generic/atomic_word.h
> +++ b/libstdc++-v3/config/cpu/generic/atomic_word.h
> @@ -29,19 +29,46 @@
> #ifndef _GLIBCXX_ATOMIC_WORD_H
> #define _GLIBCXX_ATOMIC_WORD_H 1
>
> +#include <bits/cxxabi_tweaks.h>
> +
> typedef int _Atomic_word;
>
> -// Define these two macros using the appropriate memory barrier for
> the target.
> -// The commented out versions below are the defaults.
> -// See ia64/atomic_word.h for an alternative approach.
> +
> +namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
> +{
> + // Test the first byte of __g and ensure that no loads are hoisted
> across
> + // the test.
That comment is not quite correct. I'd just say that this is a
memory_order_acquire load and a comparison.
> + inline bool
> + __test_and_acquire (__cxxabiv1::__guard *__g)
> + {
> + unsigned char __c;
> + unsigned char *__p = reinterpret_cast<unsigned char *>(__g);
> + __atomic_load (__p, &__c, __ATOMIC_ACQUIRE);
> + return __c != 0;
> + }
> +
> + // Set the first byte of __g to 1 and ensure that no stores are
> sunk
> + // across the store.
Likewise; I'd just say this is a memory_order_release store with 1 as
value.
> + inline void
> + __set_and_release (__cxxabiv1::__guard *__g)
> + {
> + unsigned char *__p = reinterpret_cast<unsigned char *>(__g);
> + unsigned char val = 1;
> + __atomic_store (__p, &val, __ATOMIC_RELEASE);
> + }
> +
> +#define _GLIBCXX_GUARD_TEST_AND_ACQUIRE(G)
> __gnu_cxx::__test_and_acquire (G)
> +#define _GLIBCXX_GUARD_SET_AND_RELEASE(G)
> __gnu_cxx::__set_and_release (G)
>
> // This one prevents loads from being hoisted across the barrier;
> // in other words, this is a Load-Load acquire barrier.
Likewise; I'd just say that this is an mo_acquire fence.
> -// This is necessary iff TARGET_RELAXED_ORDERING is defined in
> tm.h.
> -// #define _GLIBCXX_READ_MEM_BARRIER __asm __volatile ("":::"memory")
> +// This is necessary iff TARGET_RELAXED_ORDERING is defined in tm.h.
> +#define _GLIBCXX_READ_MEM_BARRIER __atomic_thread_fence
> (__ATOMIC_ACQUIRE)
>
> // This one prevents stores from being sunk across the barrier; in
> other
> // words, a Store-Store release barrier.
Likewise; mo_release fence.
> -// #define _GLIBCXX_WRITE_MEM_BARRIER __asm __volatile
> ("":::"memory")
> +#define _GLIBCXX_WRITE_MEM_BARRIER __atomic_thread_fence
> (__ATOMIC_RELEASE)
> +
> +}
>
> #endif
More information about the Libstdc++
mailing list