This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Do not copy std:call_once arguments (LWG 2442)


On 12/10/16 12:22 +0100, Jonathan Wakely wrote:
This replaces the use of std::__bind_simple by direct calls to
std::__invoke so that the arguments are not decay-copied.

	* doc/xml/manual/intro.xml: Document LWG 2442 status.
	* include/std/mutex [_GLIBCXX_HAVE_TLS] (__once_call_impl): Remove.
	[_GLIBCXX_HAVE_TLS] (_Once_call): Declare primary template and define
	partial specialization to unpack args and forward to std::invoke.
	(call_once) [_GLIBCXX_HAVE_TLS]: Use forward_as_tuple and _Once_call
	instead of __bind_simple and __once_call_impl.
	(call_once) [!_GLIBCXX_HAVE_TLS]: Use __invoke instead of
	__bind_simple.
	* testsuite/30_threads/call_once/dr2442.cc: New test.

Tested powerpc64le-linux, committed to trunk.

I don't know why I over-complicated it by packing and unpacking the
args in a tuple, this is much simpler, and makes the TLS and non-TLS
implementations more similar.

Tested powerpc64le-linux, committed to trunk.


commit f4f65251fbf84547db29d04bfa60ffcf0540a188
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Wed Oct 12 12:30:35 2016 +0100

    Simplify std::call_once implementation
    
    	* include/std/mutex [_GLIBCXX_HAVE_TLS] (_Once_call): Remove.
    	(call_once) [_GLIBCXX_HAVE_TLS]: Simplify by removing _Once_call.

diff --git a/libstdc++-v3/include/std/mutex b/libstdc++-v3/include/std/mutex
index 4c6f036..e90006f 100644
--- a/libstdc++-v3/include/std/mutex
+++ b/libstdc++-v3/include/std/mutex
@@ -579,21 +579,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #ifdef _GLIBCXX_HAVE_TLS
   extern __thread void* __once_callable;
   extern __thread void (*__once_call)();
-
-  template<typename _Tuple, typename _IndexSeq
-	   = typename _Build_index_tuple<tuple_size<_Tuple>::value>::__type>
-    struct _Once_call;
-
-  template<typename _Tuple, size_t... _Ind>
-    struct _Once_call<_Tuple, _Index_tuple<_Ind...>>
-    {
-      static void
-      _S_call()
-      {
-	auto& __f_args = *static_cast<_Tuple*>(__once_callable);
-	std::__invoke(std::get<_Ind>(std::move(__f_args))...);
-      }
-    };
 #else
   extern function<void()> __once_functor;
 
@@ -613,17 +598,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     {
       // _GLIBCXX_RESOLVE_LIB_DEFECTS
       // 2442. call_once() shouldn't DECAY_COPY()
-#ifdef _GLIBCXX_HAVE_TLS
-      auto __f_args = std::forward_as_tuple(
-	  std::forward<_Callable>(__f), std::forward<_Args>(__args)...);
-      __once_callable = std::__addressof(__f_args);
-      __once_call = _Once_call<decltype(__f_args)>::_S_call;
-#else
-      unique_lock<mutex> __functor_lock(__get_once_mutex());
-      __once_functor = [&] {
+      auto __callable = [&] {
 	  std::__invoke(std::forward<_Callable>(__f),
 			std::forward<_Args>(__args)...);
       };
+#ifdef _GLIBCXX_HAVE_TLS
+      __once_callable = std::__addressof(__callable);
+      __once_call = []{ (*(decltype(__callable)*)__once_callable)(); };
+#else
+      unique_lock<mutex> __functor_lock(__get_once_mutex());
+      __once_functor = __callable;
       __set_once_functor_lock_ptr(&__functor_lock);
 #endif
 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]