From: redi Date: Sat, 25 Apr 2009 20:14:27 +0000 (+0000) Subject: 2009-04-25 Jonathan Wakely X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=commitdiff_plain;h=2094ad2fdac49c08bb16eceac1cb8edb5c10a294;hp=f047dd27e7c115b46c20e69619df910179c76877 2009-04-25 Jonathan Wakely * include/std/mutex (__get_once_functor_lock, __get_once_mutex): Replace global lock object with local locks on global mutex. * src/mutex.cc: Likewise. * config/abi/pre/gnu.ver: Adjust. * testsuite/30_threads/call_once/call_once2.cc: New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@146785 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 8841a7060c9..60f7ef2ea2e 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,11 @@ +2009-04-25 Jonathan Wakely + + * include/std/mutex (__get_once_functor_lock, __get_once_mutex): + Replace global lock object with local locks on global mutex. + * src/mutex.cc: Likewise. + * config/abi/pre/gnu.ver: Adjust. + * testsuite/30_threads/call_once/call_once2.cc: New. + 2009-04-25 Paolo Carlini PR libstdc++/39880 diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver index 57183c1a670..bd2c63e2219 100644 --- a/libstdc++-v3/config/abi/pre/gnu.ver +++ b/libstdc++-v3/config/abi/pre/gnu.ver @@ -879,7 +879,8 @@ GLIBCXX_3.4.11 { _ZSt11__once_call; _ZSt15__once_callable; _ZSt14__once_functor; - _ZSt23__get_once_functor_lockv; + _ZSt19__once_functor_lock; + _ZSt16__get_once_mutexv; __once_proxy; # condition_variable diff --git a/libstdc++-v3/include/std/mutex b/libstdc++-v3/include/std/mutex index f26acc02f4f..3a22aabcad1 100644 --- a/libstdc++-v3/include/std/mutex +++ b/libstdc++-v3/include/std/mutex @@ -728,9 +728,10 @@ namespace std } #else extern function __once_functor; + extern unique_lock* __once_functor_lock; - extern unique_lock& - __get_once_functor_lock(); + extern mutex& + __get_once_mutex(); #endif extern "C" void __once_proxy(); @@ -745,18 +746,13 @@ namespace std __once_callable = &__bound_functor; __once_call = &__once_call_impl; #else - unique_lock& __functor_lock = __get_once_functor_lock(); - __functor_lock.lock(); + unique_lock __functor_lock(__get_once_mutex()); __once_functor = bind(__f, __args...); + __once_functor_lock = &__functor_lock; #endif int __e = __gthread_once(&(__once._M_once), &__once_proxy); -#ifndef _GLIBCXX_HAVE_TLS - if (__functor_lock) - __functor_lock.unlock(); -#endif - if (__e) __throw_system_error(__e); } diff --git a/libstdc++-v3/src/mutex.cc b/libstdc++-v3/src/mutex.cc index e0a94892158..a9467c2acd0 100644 --- a/libstdc++-v3/src/mutex.cc +++ b/libstdc++-v3/src/mutex.cc @@ -25,18 +25,6 @@ #include #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 { const defer_lock_t defer_lock = defer_lock_t(); @@ -55,11 +43,13 @@ namespace std template class function; function __once_functor; - unique_lock& - __get_once_functor_lock() + unique_lock* __once_functor_lock; + + mutex& + __get_once_mutex() { - static unique_lock once_functor_lock(get_once_mutex(), defer_lock); - return once_functor_lock; + static mutex once_mutex; + return once_mutex; } #endif @@ -69,7 +59,7 @@ namespace std { #ifndef _GLIBCXX_HAVE_TLS function __once_call = std::move(__once_functor); - __get_once_functor_lock().unlock(); + __once_functor_lock->unlock(); #endif __once_call(); } diff --git a/libstdc++-v3/testsuite/30_threads/call_once/call_once2.cc b/libstdc++-v3/testsuite/30_threads/call_once/call_once2.cc new file mode 100644 index 00000000000..aa125919bf8 --- /dev/null +++ b/libstdc++-v3/testsuite/30_threads/call_once/call_once2.cc @@ -0,0 +1,56 @@ +// { dg-do run { target *-*-freebsd* *-*-netbsd* *-*-linux* *-*-solaris* *-*-cygwin *-*-darwin* alpha*-*-osf* mips-sgi-irix6* } } +// { dg-options " -std=gnu++0x -pthread" { target *-*-freebsd* *-*-netbsd* *-*-linux* alpha*-*-osf* mips-sgi-irix6* } } +// { dg-options " -std=gnu++0x -pthreads" { target *-*-solaris* } } +// { dg-options " -std=gnu++0x " { target *-*-cygwin *-*-darwin* } } +// { dg-require-cstdint "" } +// { dg-require-gthreads "" } + +// Copyright (C) 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 +// 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. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + + +#include +#include +#include + +std::once_flag flag; +int value = 0; + +struct Inc { void operator()() const { ++value; } }; + +struct Func +{ + void operator()() const + { + Inc inc; + for (int i = 0; i < 10000; ++i) + std::call_once(flag, inc); + } +}; + +int main() +{ + Func f; + std::thread t1(f); + std::thread t2(f); + std::thread t3(f); + t1.join(); + t2.join(); + t3.join(); + VERIFY( value == 1 ); + return 0; +}