diff options
author | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-04-14 16:23:18 +0000 |
---|---|---|
committer | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-04-14 16:23:18 +0000 |
commit | ab2ba306f09948ff09fef49f3592d714c38b2d93 (patch) | |
tree | b12d13d305b3e049e0907c34ad5d505ce04fa415 /libstdc++-v3/src/atomic.cc | |
parent | a39fe8c82fd895251538269b679047bd6fc98ac5 (diff) | |
download | gcc-ab2ba306f09948ff09fef49f3592d714c38b2d93.tar.gz |
2008-04-14 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk r134275
stilly buggy for libgcc muldi3: internal compiler error: in
execute_ipa_pass_list, at passes.c:1235
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@134279 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3/src/atomic.cc')
-rw-r--r-- | libstdc++-v3/src/atomic.cc | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/libstdc++-v3/src/atomic.cc b/libstdc++-v3/src/atomic.cc new file mode 100644 index 00000000000..e43733332db --- /dev/null +++ b/libstdc++-v3/src/atomic.cc @@ -0,0 +1,116 @@ +// Support for atomic operations -*- C++ -*- + +// Copyright (C) 2008 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#include <stdint.h> +#include <cstdatomic> + +#define LOGSIZE 4 + +namespace +{ + atomic_flag volatile __atomic_flag_anon_table__[ 1 << LOGSIZE ] = + { + ATOMIC_FLAG_INIT, ATOMIC_FLAG_INIT, ATOMIC_FLAG_INIT, ATOMIC_FLAG_INIT, + ATOMIC_FLAG_INIT, ATOMIC_FLAG_INIT, ATOMIC_FLAG_INIT, ATOMIC_FLAG_INIT, + ATOMIC_FLAG_INIT, ATOMIC_FLAG_INIT, ATOMIC_FLAG_INIT, ATOMIC_FLAG_INIT, + ATOMIC_FLAG_INIT, ATOMIC_FLAG_INIT, ATOMIC_FLAG_INIT, ATOMIC_FLAG_INIT, + }; +} // anonymous namespace + +namespace std +{ + extern "C" { + + const atomic_flag atomic_global_fence_compatibility = ATOMIC_FLAG_INIT; + + bool + atomic_flag_test_and_set_explicit(volatile atomic_flag* __a, + memory_order __x) + { +#ifdef _GLIBCXX_ATOMIC_BUILTINS + if (__x >= memory_order_acq_rel) + __sync_synchronize(); + return __sync_lock_test_and_set(&(__a->_M_base._M_b), 1); +#else + bool result = __a->_M_base._M_b; + __a->_M_base._M_b = true; + return result; +#endif + } + + bool + atomic_flag_test_and_set(volatile atomic_flag* __a) + { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); } + + void + atomic_flag_clear_explicit(volatile atomic_flag* __a, memory_order __x) + { +#ifdef _GLIBCXX_ATOMIC_BUILTINS + __sync_lock_release(&(__a->_M_base._M_b)); + if (__x >= memory_order_acq_rel) + __sync_synchronize(); +#else + __a->_M_base._M_b = false; +#endif + } + + void + atomic_flag_clear(volatile atomic_flag* __a) + { atomic_flag_clear_explicit(__a, memory_order_seq_cst); } + + void + atomic_flag_fence(const volatile atomic_flag*, memory_order) + { +#ifdef _GLIBCXX_ATOMIC_BUILTINS + __sync_synchronize(); +#endif + } + + void + __atomic_flag_wait_explicit(volatile atomic_flag* __a, memory_order __x) + { + while (atomic_flag_test_and_set_explicit(__a, __x)) + { }; + } + + volatile atomic_flag* + __atomic_flag_for_address(const volatile void* __z) + { + uintptr_t __u = reinterpret_cast<uintptr_t>(__z); + __u += (__u >> 2) + (__u << 4); + __u += (__u >> 7) + (__u << 5); + __u += (__u >> 17) + (__u << 13); + if (sizeof(uintptr_t) > 4) __u += (__u >> 31); + __u &= ~((~uintptr_t(0)) << LOGSIZE); + return __atomic_flag_anon_table__ + __u; + } + + } // extern "C" +} // namespace std |