]> https://gitweb.dealii.org/ - dealii.git/commitdiff
do not launch taskflow tasks from inside tasks 18195/head
authorTimo Heister <timo.heister@gmail.com>
Wed, 11 Dec 2024 21:26:49 +0000 (16:26 -0500)
committerTimo Heister <timo.heister@gmail.com>
Thu, 6 Mar 2025 20:22:40 +0000 (15:22 -0500)
This works around the deadlocks reported in #17669

include/deal.II/base/thread_management.h

index 99a96de26d103cf380cafc73a4c6ae14c647fad0..32364ddcba2921c2c0237a36cabdbd05ddc1d786 100644 (file)
@@ -505,8 +505,14 @@ namespace Threads
       if (MultithreadInfo::n_threads() > 1)
         {
 #ifdef DEAL_II_WITH_TASKFLOW
-          task_data = std::make_shared<TaskData>(
-            MultithreadInfo::get_taskflow_executor().async(function_object));
+
+          if (MultithreadInfo::get_taskflow_executor().this_worker_id() < 0)
+            {
+              task_data = std::make_shared<TaskData>(
+                MultithreadInfo::get_taskflow_executor().async(
+                  function_object));
+              return;
+            }
 #elif defined(DEAL_II_WITH_TBB)
           // Create a promise object and from it extract a future that
           // we can use to refer to the outcome of the task. For reasons
@@ -574,6 +580,7 @@ namespace Threads
                     }
                 }
             });
+          return;
 
 #else
           // If no threading library is supported, just fall back onto C++11
@@ -596,40 +603,40 @@ namespace Threads
           task_data = std::make_shared<TaskData>(
             std::async(std::launch::async | std::launch::deferred,
                        function_object));
+          return;
 #endif
         }
-      else
-        {
-          // Only one thread allowed. So let the task run to completion
-          // and just emplace a 'ready' future.
-          //
-          // The design of std::promise/std::future is unclear, but it
-          // seems that the intent is to obtain the std::future before
-          // we set the std::promise. So create the TaskData object at
-          // the top and then run the task and set the returned
-          // value. Since everything here happens sequentially, it
-          // really doesn't matter in which order all of this is
-          // happening.
-          std::promise<RT> promise;
-          task_data = std::make_shared<TaskData>(promise.get_future());
-          try
-            {
-              internal::evaluate_and_set_promise(function_object, promise);
-            }
-          catch (...)
-            {
-              try
-                {
-                  // store anything thrown in the promise
-                  promise.set_exception(std::current_exception());
-                }
-              catch (...)
-                {
-                  // set_exception() may throw too. But ignore this on
-                  // the task.
-                }
-            }
-        }
+      {
+        // Only one thread allowed. So let the task run to completion
+        // and just emplace a 'ready' future.
+        //
+        // The design of std::promise/std::future is unclear, but it
+        // seems that the intent is to obtain the std::future before
+        // we set the std::promise. So create the TaskData object at
+        // the top and then run the task and set the returned
+        // value. Since everything here happens sequentially, it
+        // really doesn't matter in which order all of this is
+        // happening.
+        std::promise<RT> promise;
+        task_data = std::make_shared<TaskData>(promise.get_future());
+        try
+          {
+            internal::evaluate_and_set_promise(function_object, promise);
+          }
+        catch (...)
+          {
+            try
+              {
+                // store anything thrown in the promise
+                promise.set_exception(std::current_exception());
+              }
+            catch (...)
+              {
+                // set_exception() may throw too. But ignore this on
+                // the task.
+              }
+          }
+      }
     }
 
     /**

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.