OSDN Git Service

2009-04-25 Jonathan Wakely <jwakely.gcc@gmail.com>
authorredi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 25 Apr 2009 20:14:27 +0000 (20:14 +0000)
committerredi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 25 Apr 2009 20:14:27 +0000 (20:14 +0000)
* 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

libstdc++-v3/ChangeLog
libstdc++-v3/config/abi/pre/gnu.ver
libstdc++-v3/include/std/mutex
libstdc++-v3/src/mutex.cc
libstdc++-v3/testsuite/30_threads/call_once/call_once2.cc [new file with mode: 0644]

index 8841a70..60f7ef2 100644 (file)
@@ -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
index 57183c1..bd2c63e 100644 (file)
@@ -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
index f26acc0..3a22aab 100644 (file)
@@ -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);
     }
index e0a9489..a9467c2 100644 (file)
 #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();
     }
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 (file)
index 0000000..aa12591
--- /dev/null
@@ -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;
+}