shared_ptr.cc (mask, [...]): Move declaration...

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.

From-SVN: r240732
This commit is contained in:
François Dumont 2016-10-03 20:23:13 +00:00
parent ac4f79dde4
commit 38aee22c7d
4 changed files with 72 additions and 29 deletions

View File

@ -1,3 +1,10 @@
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.

View File

@ -40,6 +40,8 @@
#include <cxxabi.h> // for __cxa_demangle
#include "mutex_pool.h"
using namespace std;
namespace
@ -50,15 +52,13 @@ 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

View File

@ -0,0 +1,34 @@
// 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);
}

View File

@ -24,6 +24,21 @@
#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
@ -37,21 +52,8 @@ _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)
@ -59,10 +61,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
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)
@ -72,22 +74,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_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