re PR libstdc++/36801 (config/cpu/generic/atomicity_mutex/atomicity.h incorrectly relies on global constructor ordering)
2009-01-07 Benjamin Kosnik <bkoz@redhat.com> Jonathan Larmour <jifl@eCosCentric.com> PR libstdc++/36801 * config/cpu/generic/atomicity_mutex/atomicity.h (get_atomic_mutex): New. (__gnu_cxx::__exchange_and_add): Use it. * src/atomic.cc (get_atomic_mutex): New. * src/debug.cc (get_safe_base_mutex): New. * src/locale.cc (get_locale_cache_mutex): New. * src/mt_allocator.cc (get_freelist): New. (get_freelist_mutex): New. * src/pool_allocator.cc (get_palloc_mutex): New. * include/std/mutex (__once_functor_lock): To (__get_once_functor_lock): ...this. * src/mutex.cc (__once_mutex): Don't export, use (get_once_mutex): ...this. * config/abi/pre/gnu.ver: Adjust exports. From-SVN: r143182
This commit is contained in:
parent
f5651df1ab
commit
9982752346
@ -1,3 +1,22 @@
|
||||
2009-01-07 Benjamin Kosnik <bkoz@redhat.com>
|
||||
Jonathan Larmour <jifl@eCosCentric.com>
|
||||
|
||||
PR libstdc++/36801
|
||||
* config/cpu/generic/atomicity_mutex/atomicity.h (get_atomic_mutex):
|
||||
New.
|
||||
(__gnu_cxx::__exchange_and_add): Use it.
|
||||
* src/atomic.cc (get_atomic_mutex): New.
|
||||
* src/debug.cc (get_safe_base_mutex): New.
|
||||
* src/locale.cc (get_locale_cache_mutex): New.
|
||||
* src/mt_allocator.cc (get_freelist): New.
|
||||
(get_freelist_mutex): New.
|
||||
* src/pool_allocator.cc (get_palloc_mutex): New.
|
||||
* include/std/mutex (__once_functor_lock): To
|
||||
(__get_once_functor_lock): ...this.
|
||||
* src/mutex.cc (__once_mutex): Don't export, use
|
||||
(get_once_mutex): ...this.
|
||||
* config/abi/pre/gnu.ver: Adjust exports.
|
||||
|
||||
2009-01-07 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR libstdc++/38732
|
||||
@ -53,12 +72,12 @@
|
||||
|
||||
PR libstdc++/38384
|
||||
* crossconfig.m4: Define HAVE_FABSF for hpux crosses.
|
||||
* configure: Regenerate.
|
||||
* configure: Regenerate.
|
||||
|
||||
2009-01-05 Ben Elliston <bje@au.ibm.com>
|
||||
|
||||
* configure.ac (GLIBCXX_CHECK_STANDARD_LAYOUT): Remove invocation.
|
||||
* configure: Regenerate.
|
||||
* configure.ac (GLIBCXX_CHECK_STANDARD_LAYOUT): Remove invocation.
|
||||
* configure: Regenerate.
|
||||
|
||||
2009-01-05 Ben Elliston <bje@au.ibm.com>
|
||||
|
||||
@ -141,12 +160,12 @@
|
||||
|
||||
2008-12-17 Jack Howarth <howarth@bromo.med.uc.edu>
|
||||
|
||||
* testsuite/26_numerics/headers/cmath/c99_classification_macros_c.cc:
|
||||
* testsuite/26_numerics/headers/cmath/c99_classification_macros_c.cc:
|
||||
Don't xfail test on darwin8 or later.
|
||||
|
||||
2008-12-16 Jack Howarth <howarth@bromo.med.uc.edu>
|
||||
|
||||
* testsuite/26_numerics/headers/cmath/c99_classification_macros_c.cc:
|
||||
* testsuite/26_numerics/headers/cmath/c99_classification_macros_c.cc:
|
||||
Don't xfail excessive errors on darwin8 or later.
|
||||
|
||||
2008-12-15 Benjamin Kosnik <bkoz@redhat.com>
|
||||
|
@ -1,6 +1,6 @@
|
||||
## Linker script for GNU versioning (GNU ld 2.13.91+ only.)
|
||||
##
|
||||
## Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008
|
||||
## Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
|
||||
## Free Software Foundation, Inc.
|
||||
##
|
||||
## This file is part of the GNU ISO C++ Library. This library is free
|
||||
@ -884,9 +884,7 @@ GLIBCXX_3.4.11 {
|
||||
_ZSt11__once_call;
|
||||
_ZSt15__once_callable;
|
||||
_ZSt14__once_functor;
|
||||
_ZSt19__once_functor_lock;
|
||||
_ZSt11__once_lock;
|
||||
_ZSt12__once_mutex;
|
||||
_ZSt23__get_once_functor_lockv;
|
||||
__once_proxy;
|
||||
|
||||
# condition_variable
|
||||
|
@ -1,6 +1,6 @@
|
||||
// Low-level functions for atomic operations: Generic version -*- C++ -*-
|
||||
|
||||
// Copyright (C) 1999, 2001, 2002, 2003, 2004, 2005, 2006
|
||||
// Copyright (C) 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2009
|
||||
// Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
@ -37,7 +37,12 @@
|
||||
|
||||
namespace
|
||||
{
|
||||
__gnu_cxx::__mutex atomic_mutex;
|
||||
__gnu_cxx::__mutex&
|
||||
get_atomic_mutex()
|
||||
{
|
||||
static __gnu_cxx::__mutex atomic_mutex;
|
||||
return atomic_mutex;
|
||||
}
|
||||
} // anonymous namespace
|
||||
|
||||
_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
|
||||
@ -46,7 +51,7 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
|
||||
__attribute__ ((__unused__))
|
||||
__exchange_and_add(volatile _Atomic_word* __mem, int __val)
|
||||
{
|
||||
__gnu_cxx::__scoped_lock sentry(atomic_mutex);
|
||||
__gnu_cxx::__scoped_lock sentry(get_atomic_mutex());
|
||||
_Atomic_word __result;
|
||||
__result = *__mem;
|
||||
*__mem += __val;
|
||||
|
@ -1,6 +1,6 @@
|
||||
// <mutex> -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008
|
||||
// Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009
|
||||
// Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
@ -709,13 +709,16 @@ namespace std
|
||||
extern __thread void (*__once_call)();
|
||||
|
||||
template<typename _Callable>
|
||||
void __once_call_impl()
|
||||
inline void
|
||||
__once_call_impl()
|
||||
{
|
||||
(*(_Callable*)__once_callable)();
|
||||
}
|
||||
#else
|
||||
extern function<void()> __once_functor;
|
||||
extern unique_lock<mutex> __once_functor_lock;
|
||||
|
||||
extern unique_lock<mutex>&
|
||||
__get_once_functor_lock();
|
||||
#endif
|
||||
|
||||
extern "C" void __once_proxy();
|
||||
@ -729,15 +732,16 @@ namespace std
|
||||
__once_callable = &__bound_functor;
|
||||
__once_call = &__once_call_impl<decltype(__bound_functor)>;
|
||||
#else
|
||||
__once_functor_lock.lock();
|
||||
unique_lock<mutex>& __functor_lock = __get_once_functor_lock();
|
||||
__functor_lock.lock();
|
||||
__once_functor = bind(__f, __args...);
|
||||
#endif
|
||||
|
||||
int __e = __gthread_once(&(__once._M_once), &__once_proxy);
|
||||
|
||||
#ifndef _GLIBCXX_HAVE_TLS
|
||||
if (__once_functor_lock)
|
||||
__once_functor_lock.unlock();
|
||||
if (__functor_lock)
|
||||
__functor_lock.unlock();
|
||||
#endif
|
||||
|
||||
if (__e)
|
||||
|
@ -1,6 +1,6 @@
|
||||
// Support for atomic operations -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2008
|
||||
// Copyright (C) 2008, 2009
|
||||
// Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
@ -37,7 +37,12 @@
|
||||
namespace
|
||||
{
|
||||
#if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1)
|
||||
std::mutex atomic_mutex;
|
||||
std::mutex&
|
||||
get_atomic_mutex()
|
||||
{
|
||||
static std::mutex atomic_mutex;
|
||||
return atomic_mutex;
|
||||
}
|
||||
#endif
|
||||
|
||||
std::__atomic_flag_base volatile flag_table[ 1 << LOGSIZE ] =
|
||||
@ -57,7 +62,7 @@ namespace std
|
||||
atomic_flag::test_and_set(memory_order) volatile
|
||||
{
|
||||
#if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1)
|
||||
lock_guard<mutex> __lock(atomic_mutex);
|
||||
lock_guard<mutex> __lock(get_atomic_mutex());
|
||||
#endif
|
||||
bool result = _M_i;
|
||||
_M_i = true;
|
||||
@ -68,7 +73,7 @@ namespace std
|
||||
atomic_flag::clear(memory_order) volatile
|
||||
{
|
||||
#if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1)
|
||||
lock_guard<mutex> __lock(atomic_mutex);
|
||||
lock_guard<mutex> __lock(get_atomic_mutex());
|
||||
#endif
|
||||
_M_i = false;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
// Debugging mode support code -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2003, 2004, 2005, 2006, 2007
|
||||
// Copyright (C) 2003, 2004, 2005, 2006, 2007, 2009
|
||||
// Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
@ -42,7 +42,12 @@ using namespace std;
|
||||
|
||||
namespace
|
||||
{
|
||||
__gnu_cxx::__mutex safe_base_mutex;
|
||||
__gnu_cxx::__mutex&
|
||||
get_safe_base_mutex()
|
||||
{
|
||||
static __gnu_cxx::__mutex safe_base_mutex;
|
||||
return safe_base_mutex;
|
||||
}
|
||||
} // anonymous namespace
|
||||
|
||||
namespace __gnu_debug
|
||||
@ -112,7 +117,7 @@ namespace __gnu_debug
|
||||
_Safe_sequence_base::
|
||||
_M_detach_all()
|
||||
{
|
||||
__gnu_cxx::__scoped_lock sentry(safe_base_mutex);
|
||||
__gnu_cxx::__scoped_lock sentry(_M_get_mutex());
|
||||
for (_Safe_iterator_base* __iter = _M_iterators; __iter;)
|
||||
{
|
||||
_Safe_iterator_base* __old = __iter;
|
||||
@ -132,7 +137,7 @@ namespace __gnu_debug
|
||||
_Safe_sequence_base::
|
||||
_M_detach_singular()
|
||||
{
|
||||
__gnu_cxx::__scoped_lock sentry(safe_base_mutex);
|
||||
__gnu_cxx::__scoped_lock sentry(_M_get_mutex());
|
||||
for (_Safe_iterator_base* __iter = _M_iterators; __iter;)
|
||||
{
|
||||
_Safe_iterator_base* __old = __iter;
|
||||
@ -154,7 +159,7 @@ namespace __gnu_debug
|
||||
_Safe_sequence_base::
|
||||
_M_revalidate_singular()
|
||||
{
|
||||
__gnu_cxx::__scoped_lock sentry(safe_base_mutex);
|
||||
__gnu_cxx::__scoped_lock sentry(_M_get_mutex());
|
||||
for (_Safe_iterator_base* __iter = _M_iterators; __iter;
|
||||
__iter = __iter->_M_next)
|
||||
__iter->_M_version = _M_version;
|
||||
@ -168,7 +173,7 @@ namespace __gnu_debug
|
||||
_Safe_sequence_base::
|
||||
_M_swap(_Safe_sequence_base& __x)
|
||||
{
|
||||
__gnu_cxx::__scoped_lock sentry(safe_base_mutex);
|
||||
__gnu_cxx::__scoped_lock sentry(_M_get_mutex());
|
||||
swap(_M_iterators, __x._M_iterators);
|
||||
swap(_M_const_iterators, __x._M_const_iterators);
|
||||
swap(_M_version, __x._M_version);
|
||||
@ -186,13 +191,13 @@ namespace __gnu_debug
|
||||
__gnu_cxx::__mutex&
|
||||
_Safe_sequence_base::
|
||||
_M_get_mutex()
|
||||
{ return safe_base_mutex; }
|
||||
{ return get_safe_base_mutex(); }
|
||||
|
||||
void
|
||||
_Safe_iterator_base::
|
||||
_M_attach(_Safe_sequence_base* __seq, bool __constant)
|
||||
{
|
||||
__gnu_cxx::__scoped_lock sentry(safe_base_mutex);
|
||||
__gnu_cxx::__scoped_lock sentry(_M_get_mutex());
|
||||
_M_attach_single(__seq, __constant);
|
||||
}
|
||||
|
||||
@ -229,7 +234,7 @@ namespace __gnu_debug
|
||||
_Safe_iterator_base::
|
||||
_M_detach()
|
||||
{
|
||||
__gnu_cxx::__scoped_lock sentry(safe_base_mutex);
|
||||
__gnu_cxx::__scoped_lock sentry(_M_get_mutex());
|
||||
_M_detach_single();
|
||||
}
|
||||
|
||||
@ -273,7 +278,7 @@ namespace __gnu_debug
|
||||
__gnu_cxx::__mutex&
|
||||
_Safe_iterator_base::
|
||||
_M_get_mutex()
|
||||
{ return safe_base_mutex; }
|
||||
{ return get_safe_base_mutex(); }
|
||||
|
||||
void
|
||||
_Error_formatter::_Parameter::
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
|
||||
// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
|
||||
// 2009
|
||||
// Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
@ -36,7 +37,12 @@
|
||||
|
||||
namespace
|
||||
{
|
||||
__gnu_cxx::__mutex locale_cache_mutex;
|
||||
__gnu_cxx::__mutex&
|
||||
get_locale_cache_mutex()
|
||||
{
|
||||
static __gnu_cxx::__mutex locale_cache_mutex;
|
||||
return locale_cache_mutex;
|
||||
}
|
||||
} // anonymous namespace
|
||||
|
||||
// XXX GLIBCXX_ABI Deprecated
|
||||
@ -389,7 +395,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
|
||||
locale::_Impl::
|
||||
_M_install_cache(const facet* __cache, size_t __index)
|
||||
{
|
||||
__gnu_cxx::__scoped_lock sentry(locale_cache_mutex);
|
||||
__gnu_cxx::__scoped_lock sentry(get_locale_cache_mutex());
|
||||
if (_M_caches[__index] != 0)
|
||||
{
|
||||
// Some other thread got in first.
|
||||
|
@ -1,6 +1,6 @@
|
||||
// Allocator details.
|
||||
|
||||
// Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
|
||||
// Copyright (C) 2004, 2005, 2006, 2009 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
|
||||
@ -57,21 +57,34 @@ namespace
|
||||
}
|
||||
};
|
||||
|
||||
// Ensure freelist is constructed first.
|
||||
static __freelist freelist;
|
||||
__gnu_cxx::__mutex freelist_mutex;
|
||||
__freelist&
|
||||
get_freelist()
|
||||
{
|
||||
static __freelist freelist;
|
||||
return freelist;
|
||||
}
|
||||
|
||||
__gnu_cxx::__mutex&
|
||||
get_freelist_mutex()
|
||||
{
|
||||
static __gnu_cxx::__mutex freelist_mutex;
|
||||
return freelist_mutex;
|
||||
}
|
||||
|
||||
static void
|
||||
_M_destroy_thread_key(void* __id)
|
||||
{
|
||||
// Return this thread id record to the front of thread_freelist.
|
||||
__gnu_cxx::__scoped_lock sentry(freelist_mutex);
|
||||
size_t _M_id = reinterpret_cast<size_t>(__id);
|
||||
|
||||
typedef __gnu_cxx::__pool<true>::_Thread_record _Thread_record;
|
||||
_Thread_record* __tr = &freelist._M_thread_freelist_array[_M_id - 1];
|
||||
__tr->_M_next = freelist._M_thread_freelist;
|
||||
freelist._M_thread_freelist = __tr;
|
||||
__freelist& freelist = get_freelist();
|
||||
{
|
||||
__gnu_cxx::__scoped_lock sentry(get_freelist_mutex());
|
||||
size_t _M_id = reinterpret_cast<size_t>(__id);
|
||||
|
||||
typedef __gnu_cxx::__pool<true>::_Thread_record _Thread_record;
|
||||
_Thread_record* __tr = &freelist._M_thread_freelist_array[_M_id - 1];
|
||||
__tr->_M_next = freelist._M_thread_freelist;
|
||||
freelist._M_thread_freelist = __tr;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} // anonymous namespace
|
||||
@ -496,8 +509,9 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
|
||||
// directly and have no need for this.
|
||||
if (__gthread_active_p())
|
||||
{
|
||||
__freelist& freelist = get_freelist();
|
||||
{
|
||||
__gnu_cxx::__scoped_lock sentry(freelist_mutex);
|
||||
__gnu_cxx::__scoped_lock sentry(get_freelist_mutex());
|
||||
|
||||
if (!freelist._M_thread_freelist_array
|
||||
|| freelist._M_max_threads < _M_options._M_max_threads)
|
||||
@ -613,12 +627,13 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
|
||||
// returns its id.
|
||||
if (__gthread_active_p())
|
||||
{
|
||||
__freelist& freelist = get_freelist();
|
||||
void* v = __gthread_getspecific(freelist._M_key);
|
||||
size_t _M_id = (size_t)v;
|
||||
if (_M_id == 0)
|
||||
{
|
||||
{
|
||||
__gnu_cxx::__scoped_lock sentry(freelist_mutex);
|
||||
__gnu_cxx::__scoped_lock sentry(get_freelist_mutex());
|
||||
if (freelist._M_thread_freelist)
|
||||
{
|
||||
_M_id = freelist._M_thread_freelist->_M_id;
|
||||
@ -689,8 +704,9 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
|
||||
// directly and have no need for this.
|
||||
if (__gthread_active_p())
|
||||
{
|
||||
__freelist& freelist = get_freelist();
|
||||
{
|
||||
__gnu_cxx::__scoped_lock sentry(freelist_mutex);
|
||||
__gnu_cxx::__scoped_lock sentry(get_freelist_mutex());
|
||||
|
||||
if (!freelist._M_thread_freelist_array
|
||||
|| freelist._M_max_threads < _M_options._M_max_threads)
|
||||
|
@ -1,6 +1,6 @@
|
||||
// mutex -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2008 Free Software Foundation, Inc.
|
||||
// Copyright (C) 2008, 2009 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
|
||||
@ -30,6 +30,17 @@
|
||||
#include <mutex>
|
||||
|
||||
#if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1)
|
||||
#ifndef _GLIBCXX_HAVE_TLS
|
||||
namespace
|
||||
{
|
||||
std::mutex&
|
||||
get_once_mutex()
|
||||
{
|
||||
static std::mutex once_mutex;
|
||||
return once_mutex;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace std
|
||||
{
|
||||
@ -45,11 +56,16 @@ namespace std
|
||||
__thread void* __once_callable;
|
||||
__thread void (*__once_call)();
|
||||
#else
|
||||
// explicit instantiation due to -fno-implicit-instantiation
|
||||
// Explicit instantiation due to -fno-implicit-instantiation.
|
||||
template class function<void()>;
|
||||
function<void()> __once_functor;
|
||||
mutex __once_mutex;
|
||||
unique_lock<mutex> __once_functor_lock(__once_mutex, defer_lock);
|
||||
|
||||
unique_lock<mutex>&
|
||||
__get_once_functor_lock()
|
||||
{
|
||||
static unique_lock<mutex> once_functor_lock(get_once_mutex(), defer_lock);
|
||||
return once_functor_lock;
|
||||
}
|
||||
#endif
|
||||
|
||||
extern "C"
|
||||
@ -58,7 +74,7 @@ namespace std
|
||||
{
|
||||
#ifndef _GLIBCXX_HAVE_TLS
|
||||
function<void()> __once_call = std::move(__once_functor);
|
||||
__once_functor_lock.unlock();
|
||||
__get_once_functor_lock().unlock();
|
||||
#endif
|
||||
__once_call();
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
// Allocator details.
|
||||
|
||||
// Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
|
||||
// Copyright (C) 2004, 2005, 2006, 2009 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
|
||||
@ -37,7 +37,12 @@
|
||||
|
||||
namespace
|
||||
{
|
||||
__gnu_cxx::__mutex palloc_init_mutex;
|
||||
__gnu_cxx::__mutex&
|
||||
get_palloc_mutex()
|
||||
{
|
||||
static __gnu_cxx::__mutex palloc_mutex;
|
||||
return palloc_mutex;
|
||||
}
|
||||
} // anonymous namespace
|
||||
|
||||
_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
|
||||
@ -52,7 +57,7 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
|
||||
|
||||
__mutex&
|
||||
__pool_alloc_base::_M_get_mutex()
|
||||
{ return palloc_init_mutex; }
|
||||
{ return get_palloc_mutex(); }
|
||||
|
||||
// Allocate memory in large chunks in order to avoid fragmenting the
|
||||
// heap too much. Assume that __n is properly aligned. We hold the
|
||||
|
Loading…
Reference in New Issue
Block a user