summaryrefslogtreecommitdiff
path: root/libstdc++-v3/src/atomic.cc
diff options
context:
space:
mode:
authorbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2008-04-14 16:23:18 +0000
committerbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2008-04-14 16:23:18 +0000
commitab2ba306f09948ff09fef49f3592d714c38b2d93 (patch)
treeb12d13d305b3e049e0907c34ad5d505ce04fa415 /libstdc++-v3/src/atomic.cc
parenta39fe8c82fd895251538269b679047bd6fc98ac5 (diff)
downloadgcc-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.cc116
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