+2016-10-03 François Dumont <fdumont@gcc.gnu.org>
+
+ * src/c++11/shared_ptr.cc (mask, invalid, get_mutex): Move
+ declaration...
+ * src/c++11/mutex_pool.h: ... here. New.
+ * src/c++11/debug.cc: Use latter.
+
2016-10-03 Jonathan Wakely <jwakely@redhat.com>
* doc/xml/manual/status_cxx2017.xml: Update gcd/lcm status.
#include <cxxabi.h> // for __cxa_demangle
+#include "mutex_pool.h"
+
using namespace std;
namespace
__gnu_cxx::__mutex&
get_safe_base_mutex(void* address)
{
- const size_t mask = 0xf;
- static __gnu_cxx::__mutex safe_base_mutex[mask + 1];
-
// Use arbitrarily __gnu_debug::vector<int> as the container giving
// alignment of debug containers.
const auto alignbits = __builtin_ctz(alignof(__gnu_debug::vector<int>));
- const size_t index
- = (reinterpret_cast<std::size_t>(address) >> alignbits) & mask;
- return safe_base_mutex[index];
+ const unsigned char index
+ = (reinterpret_cast<std::size_t>(address) >> alignbits)
+ & __gnu_internal::mask;
+ return __gnu_internal::get_mutex(index);
}
void
--- /dev/null
+// Mutex pool used to limit contention -*- C++ -*-
+
+// Copyright (C) 2016 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 3, 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.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+// <http://www.gnu.org/licenses/>.
+
+namespace __gnu_internal _GLIBCXX_VISIBILITY(hidden)
+{
+ const unsigned char mask = 0xf;
+ const unsigned char invalid = mask + 1;
+
+ /* Returns different instances of __mutex depending on the passed index
+ * in order to limit contention.
+ */
+ __gnu_cxx::__mutex& get_mutex(unsigned char i);
+}
#include <memory>
+#include "mutex_pool.h"
+
+namespace __gnu_internal _GLIBCXX_VISIBILITY(hidden)
+{
+ /* Returns different instances of __mutex depending on the passed index
+ * in order to limit contention.
+ */
+ __gnu_cxx::__mutex&
+ get_mutex(unsigned char i)
+ {
+ static __gnu_cxx::__mutex m[mask + 1];
+ return m[i];
+ }
+}
+
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
#ifdef __GTHREADS
namespace
{
- const unsigned char mask = 0xf;
- const unsigned char invalid = mask + 1;
-
inline unsigned char key(const void* addr)
- { return _Hash_impl::hash(addr) & mask; }
-
- /* Returns different instances of __mutex depending on the passed address
- * in order to limit contention.
- */
- __gnu_cxx::__mutex&
- get_mutex(unsigned char i)
- {
- static __gnu_cxx::__mutex m[mask + 1];
- return m[i];
- }
+ { return _Hash_impl::hash(addr) & __gnu_internal::mask; }
}
_Sp_locker::_Sp_locker(const void* p)
if (__gthread_active_p())
{
_M_key1 = _M_key2 = key(p);
- get_mutex(_M_key1).lock();
+ __gnu_internal::get_mutex(_M_key1).lock();
}
else
- _M_key1 = _M_key2 = invalid;
+ _M_key1 = _M_key2 = __gnu_internal::invalid;
}
_Sp_locker::_Sp_locker(const void* p1, const void* p2)
_M_key1 = key(p1);
_M_key2 = key(p2);
if (_M_key2 < _M_key1)
- get_mutex(_M_key2).lock();
- get_mutex(_M_key1).lock();
+ __gnu_internal::get_mutex(_M_key2).lock();
+ __gnu_internal::get_mutex(_M_key1).lock();
if (_M_key2 > _M_key1)
- get_mutex(_M_key2).lock();
+ __gnu_internal::get_mutex(_M_key2).lock();
}
else
- _M_key1 = _M_key2 = invalid;
+ _M_key1 = _M_key2 = __gnu_internal::invalid;
}
_Sp_locker::~_Sp_locker()
{
- if (_M_key1 != invalid)
+ if (_M_key1 != __gnu_internal::invalid)
{
- get_mutex(_M_key1).unlock();
+ __gnu_internal::get_mutex(_M_key1).unlock();
if (_M_key2 != _M_key1)
- get_mutex(_M_key2).unlock();
+ __gnu_internal::get_mutex(_M_key2).unlock();
}
}
#endif