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>
|
||||
|
||||
PR libstdc++/39880
|
||||
|
@ -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
|
||||
|
@ -728,9 +728,10 @@ namespace std
|
||||
}
|
||||
#else
|
||||
extern function<void()> __once_functor;
|
||||
extern unique_lock<mutex>* __once_functor_lock;
|
||||
|
||||
extern unique_lock<mutex>&
|
||||
__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<decltype(__bound_functor)>;
|
||||
#else
|
||||
unique_lock<mutex>& __functor_lock = __get_once_functor_lock();
|
||||
__functor_lock.lock();
|
||||
unique_lock<mutex> __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);
|
||||
}
|
||||
|
@ -25,18 +25,6 @@
|
||||
#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
|
||||
{
|
||||
const defer_lock_t defer_lock = defer_lock_t();
|
||||
@ -55,11 +43,13 @@ namespace std
|
||||
template class function<void()>;
|
||||
function<void()> __once_functor;
|
||||
|
||||
unique_lock<mutex>&
|
||||
__get_once_functor_lock()
|
||||
unique_lock<mutex>* __once_functor_lock;
|
||||
|
||||
mutex&
|
||||
__get_once_mutex()
|
||||
{
|
||||
static unique_lock<mutex> 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<void()> __once_call = std::move(__once_functor);
|
||||
__get_once_functor_lock().unlock();
|
||||
__once_functor_lock->unlock();
|
||||
#endif
|
||||
__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