mutex (__get_once_functor_lock, [...]): Replace global lock object with local locks on global mutex.
2009-04-25 Jonathan Wakely <jwakely.gcc@gmail.com> * 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. From-SVN: r146785
This commit is contained in:
parent
d6d89aa1c4
commit
afdb7762cb
@ -1,3 +1,11 @@
|
|||||||
|
2009-04-25 Jonathan Wakely <jwakely.gcc@gmail.com>
|
||||||
|
|
||||||
|
* 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 <paolo.carlini@oracle.com>
|
2009-04-25 Paolo Carlini <paolo.carlini@oracle.com>
|
||||||
|
|
||||||
PR libstdc++/39880
|
PR libstdc++/39880
|
||||||
|
@ -879,7 +879,8 @@ GLIBCXX_3.4.11 {
|
|||||||
_ZSt11__once_call;
|
_ZSt11__once_call;
|
||||||
_ZSt15__once_callable;
|
_ZSt15__once_callable;
|
||||||
_ZSt14__once_functor;
|
_ZSt14__once_functor;
|
||||||
_ZSt23__get_once_functor_lockv;
|
_ZSt19__once_functor_lock;
|
||||||
|
_ZSt16__get_once_mutexv;
|
||||||
__once_proxy;
|
__once_proxy;
|
||||||
|
|
||||||
# condition_variable
|
# condition_variable
|
||||||
|
@ -728,9 +728,10 @@ namespace std
|
|||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
extern function<void()> __once_functor;
|
extern function<void()> __once_functor;
|
||||||
|
extern unique_lock<mutex>* __once_functor_lock;
|
||||||
|
|
||||||
extern unique_lock<mutex>&
|
extern mutex&
|
||||||
__get_once_functor_lock();
|
__get_once_mutex();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern "C" void __once_proxy();
|
extern "C" void __once_proxy();
|
||||||
@ -745,18 +746,13 @@ namespace std
|
|||||||
__once_callable = &__bound_functor;
|
__once_callable = &__bound_functor;
|
||||||
__once_call = &__once_call_impl<decltype(__bound_functor)>;
|
__once_call = &__once_call_impl<decltype(__bound_functor)>;
|
||||||
#else
|
#else
|
||||||
unique_lock<mutex>& __functor_lock = __get_once_functor_lock();
|
unique_lock<mutex> __functor_lock(__get_once_mutex());
|
||||||
__functor_lock.lock();
|
|
||||||
__once_functor = bind(__f, __args...);
|
__once_functor = bind(__f, __args...);
|
||||||
|
__once_functor_lock = &__functor_lock;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int __e = __gthread_once(&(__once._M_once), &__once_proxy);
|
int __e = __gthread_once(&(__once._M_once), &__once_proxy);
|
||||||
|
|
||||||
#ifndef _GLIBCXX_HAVE_TLS
|
|
||||||
if (__functor_lock)
|
|
||||||
__functor_lock.unlock();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (__e)
|
if (__e)
|
||||||
__throw_system_error(__e);
|
__throw_system_error(__e);
|
||||||
}
|
}
|
||||||
|
@ -25,18 +25,6 @@
|
|||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
#if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1)
|
#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
|
namespace std
|
||||||
{
|
{
|
||||||
const defer_lock_t defer_lock = defer_lock_t();
|
const defer_lock_t defer_lock = defer_lock_t();
|
||||||
@ -55,11 +43,13 @@ namespace std
|
|||||||
template class function<void()>;
|
template class function<void()>;
|
||||||
function<void()> __once_functor;
|
function<void()> __once_functor;
|
||||||
|
|
||||||
unique_lock<mutex>&
|
unique_lock<mutex>* __once_functor_lock;
|
||||||
__get_once_functor_lock()
|
|
||||||
|
mutex&
|
||||||
|
__get_once_mutex()
|
||||||
{
|
{
|
||||||
static unique_lock<mutex> once_functor_lock(get_once_mutex(), defer_lock);
|
static mutex once_mutex;
|
||||||
return once_functor_lock;
|
return once_mutex;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -69,7 +59,7 @@ namespace std
|
|||||||
{
|
{
|
||||||
#ifndef _GLIBCXX_HAVE_TLS
|
#ifndef _GLIBCXX_HAVE_TLS
|
||||||
function<void()> __once_call = std::move(__once_functor);
|
function<void()> __once_call = std::move(__once_functor);
|
||||||
__get_once_functor_lock().unlock();
|
__once_functor_lock->unlock();
|
||||||
#endif
|
#endif
|
||||||
__once_call();
|
__once_call();
|
||||||
}
|
}
|
||||||
|
56
libstdc++-v3/testsuite/30_threads/call_once/call_once2.cc
Normal file
56
libstdc++-v3/testsuite/30_threads/call_once/call_once2.cc
Normal file
@ -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
|
||||||
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
#include <thread>
|
||||||
|
#include <testsuite_hooks.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user