[Bf-blender-cvs] [25d30e6c99a] blender-v3.0-release: Fix T92857: Deadlock in geometry nodes curve multi-threading

Hans Goudey noreply at git.blender.org
Tue Nov 16 21:50:07 CET 2021


Commit: 25d30e6c99a2d89bf7babfacb24a8c8aa61b3b3b
Author: Hans Goudey
Date:   Tue Nov 16 14:49:58 2021 -0600
Branches: blender-v3.0-release
https://developer.blender.org/rB25d30e6c99a2d89bf7babfacb24a8c8aa61b3b3b

Fix T92857: Deadlock in geometry nodes curve multi-threading

The spline code, especially Bezier splines, often make use of lazily
evaluation and caching. In order to do that, they use mutex locks.
When multi-threading, this can lead to problems. Further detail
can be found in rBfcc844f8fbd0d1.

To fix the deadlock, isolate the task before multi-threading
when holding a lock.

Differential Revision: https://developer.blender.org/D13229

===================================================================

M	source/blender/blenkernel/intern/spline_bezier.cc

===================================================================

diff --git a/source/blender/blenkernel/intern/spline_bezier.cc b/source/blender/blenkernel/intern/spline_bezier.cc
index 166fe0f5464..18d195f19da 100644
--- a/source/blender/blenkernel/intern/spline_bezier.cc
+++ b/source/blender/blenkernel/intern/spline_bezier.cc
@@ -599,7 +599,10 @@ Span<float> BezierSpline::evaluated_mappings() const
 
   Span<int> offsets = this->control_point_offsets();
 
-  calculate_mappings_linear_resolution(offsets, size, resolution_, is_cyclic_, mappings);
+  blender::threading::isolate_task([&]() {
+    /* Isolate the task, since this is function is multi-threaded and holds a lock. */
+    calculate_mappings_linear_resolution(offsets, size, resolution_, is_cyclic_, mappings);
+  });
 
   mapping_cache_dirty_ = false;
   return mappings;
@@ -635,10 +638,13 @@ Span<float3> BezierSpline::evaluated_positions() const
   Span<int> offsets = this->control_point_offsets();
 
   const int grain_size = std::max(512 / resolution_, 1);
-  blender::threading::parallel_for(IndexRange(size - 1), grain_size, [&](IndexRange range) {
-    for (const int i : range) {
-      this->evaluate_segment(i, i + 1, positions.slice(offsets[i], offsets[i + 1] - offsets[i]));
-    }
+  blender::threading::isolate_task([&]() {
+    /* Isolate the task, since this is function is multi-threaded and holds a lock. */
+    blender::threading::parallel_for(IndexRange(size - 1), grain_size, [&](IndexRange range) {
+      for (const int i : range) {
+        this->evaluate_segment(i, i + 1, positions.slice(offsets[i], offsets[i + 1] - offsets[i]));
+      }
+    });
   });
   if (is_cyclic_) {
     this->evaluate_segment(



More information about the Bf-blender-cvs mailing list