]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Avoid locking in some cases. 17356/head
authorWolfgang Bangerth <bangerth@colostate.edu>
Tue, 23 Jul 2024 17:31:13 +0000 (11:31 -0600)
committerWolfgang Bangerth <bangerth@colostate.edu>
Tue, 23 Jul 2024 17:31:13 +0000 (11:31 -0600)
include/deal.II/base/task_result.h

index 52fc11edc872abd7bef0eff1d0824e685b8b739d..fa62e99f0aaa30350379c8f0d8d0fb345fc8f7a6 100644 (file)
@@ -521,26 +521,33 @@ namespace Threads
   inline bool
   TaskResult<T>::empty() const
   {
-    // If we have waited before, then return immediately:
+    // If we have waited for a task to complete, then the object is not empty:
     if (result_is_available)
       return false;
+    // Otherwise, if result_is_available has not been set, but we have a task
+    // associated (i.e., the task is still running, or at least we haven't
+    // waited for it to complete), then the object is also not empty:
+    else if (task.has_value())
+      return false;
     else
-      // If we have not waited, wait now. We need to use the double-checking
-      // pattern to ensure that if two threads get to this place at the same
-      // time, one returns right away while the other does the work. Note
-      // that this happens under the lock, so only one thread gets to be in
-      // this code block at the same time:
+      // If when we asked above we had not joined a task, and if there was
+      // no task currently associated with the object, then one of two cases
+      // could have happened: either, there never was a task, and the object
+      // is consequently empty. Or there was a task and somewhere between the
+      // checks above and now, join() has flipped the state to
+      // result_is_available==true and task.has_value()==false. We can
+      // check that, but only under a lock.
       {
         std::lock_guard<std::mutex> lock(mutex);
         if (result_is_available)
           return false;
         else
-          // If there is a task, then this object is not empty. Otherwise, we
-          // have no result and no task, so the object is empty:
-          if (task.has_value())
-            return false;
-          else
-            return true;
+          // We know from getting into the above 'else that no task was
+          // associated with this object at the time. This cannot have
+          // changed since then in a way that is thread-safe (i.e., by
+          // way of other 'const' functions), so if the result is still
+          // not available, then the object must necessarily be empty:
+          return true;
       }
   }
 

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.