re PR libstdc++/36801 (config/cpu/generic/atomicity_mutex/atomicity.h incorrectly...
authorBenjamin Kosnik <bkoz@gcc.gnu.org>
Thu, 8 Jan 2009 03:14:24 +0000 (03:14 +0000)
committerBenjamin Kosnik <bkoz@gcc.gnu.org>
Thu, 8 Jan 2009 03:14:24 +0000 (03:14 +0000)
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

libstdc++-v3/ChangeLog
libstdc++-v3/config/abi/pre/gnu.ver
libstdc++-v3/config/cpu/generic/atomicity_mutex/atomicity.h
libstdc++-v3/include/std/mutex
libstdc++-v3/src/atomic.cc
libstdc++-v3/src/debug.cc
libstdc++-v3/src/locale.cc
libstdc++-v3/src/mt_allocator.cc
libstdc++-v3/src/mutex.cc
libstdc++-v3/src/pool_allocator.cc

index ed698d3..02bfce7 100644 (file)
@@ -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
 
        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>
 
 
 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>
index 477604a..833435d 100644 (file)
@@ -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
index e9ee10c..c2a9c3a 100644 (file)
@@ -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
 
 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;
index e392236..4964bb3 100644 (file)
@@ -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)
index 9e6444d..5cb3919 100644 (file)
@@ -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
 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;
     }
index 0391368..4b7fac7 100644 (file)
@@ -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::
index a760994..7c30fc0 100644 (file)
@@ -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
 
 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.
index 1e64227..3430ad3 100644 (file)
@@ -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)
index 8fae030..26435a2 100644 (file)
@@ -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
 #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();
     }
index c759327..bcf9d36 100644 (file)
@@ -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
 
 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