Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/Ultimaker/CuraEngine.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRemco Burema <r.burema@ultimaker.com>2022-04-20 22:01:40 +0300
committerRemco Burema <r.burema@ultimaker.com>2022-04-20 22:01:40 +0300
commit615896c97c8a90fff444d0767937ae03bd5e8fd1 (patch)
tree38ae6f8a43a8782d8d50f9710ca0b044de9dc2ca
parentf2a3b6fe97b1008640214c8688d17300a40c0618 (diff)
Alternate fix for crashes/deadlocks Tree-Support.
Other fix could still crash and deadlock. Could have probably made it work, but the critical section using 'volumes_' within the scope of the parallel for can be very small, since the access to the tree envelope cash ('volumes_') occurs twice in quick succession. Much easier to make it its own little critical section and not worry about making that entire class thread-safe. That takes care of the crash. During investigation it was found that, since it had multiple critical sections in the loop, handled by the same mutex, _and_ a seprate atomic that was then accessed _inside_ one of the critical sections (what was I thinking...) it could deadlock or at the very least report the wrong progress (causing that part of the front-end to hang). Fixed that as well. part of CURA-9159
-rw-r--r--src/TreeSupport.cpp22
1 files changed, 11 insertions, 11 deletions
diff --git a/src/TreeSupport.cpp b/src/TreeSupport.cpp
index 6edfa7f29..b9ac0421b 100644
--- a/src/TreeSupport.cpp
+++ b/src/TreeSupport.cpp
@@ -99,8 +99,9 @@ void TreeSupport::drawCircles(SliceDataStorage& storage, const std::vector<std::
const size_t tip_layers = (branch_radius - minimum_tip_radius) / layer_height; //The number of layers to be shrinking the circle to create a tip. This produces a 45 degree angle.
const coord_t resolution = mesh_group_settings.get<coord_t>("support_tree_collision_resolution");
- std::atomic<size_t> completed = 0; //To track progress in a multi-threaded environment.
- std::mutex critical_sections;
+ size_t completed = 0; //To track progress, should be locked when altered.
+ std::mutex critical_section_volumes;
+ std::mutex critical_section_progress;
cura::parallel_for<size_t>(0, contact_nodes.size(), 1, [&](const size_t layer_nr)
{
Polygons support_layer;
@@ -142,8 +143,12 @@ void TreeSupport::drawCircles(SliceDataStorage& storage, const std::vector<std::
support_layer = support_layer.unionPolygons();
roof_layer = roof_layer.unionPolygons();
const size_t z_collision_layer = static_cast<size_t>(std::max(0, static_cast<int>(layer_nr) - static_cast<int>(z_distance_bottom_layers) + 1)); //Layer to test against to create a Z-distance.
- support_layer = support_layer.difference(volumes_.getCollision(0, z_collision_layer)); //Subtract the model itself (sample 0 is with 0 diameter but proper X/Y offset).
- roof_layer = roof_layer.difference(volumes_.getCollision(0, z_collision_layer));
+ {
+ const std::lock_guard<std::mutex> lock(critical_section_volumes);
+
+ support_layer = support_layer.difference(volumes_.getCollision(0, z_collision_layer)); //Subtract the model itself (sample 0 is with 0 diameter but proper X/Y offset).
+ roof_layer = roof_layer.difference(volumes_.getCollision(0, z_collision_layer));
+ }
support_layer = support_layer.difference(roof_layer);
//We smooth this support as much as possible without altering single circles. So we remove any line less than the side length of those circles.
const double diameter_angle_scale_factor_this_layer = static_cast<double>(storage.support.supportLayers.size() - layer_nr - tip_layers) * diameter_angle_scale_factor; //Maximum scale factor.
@@ -181,19 +186,14 @@ void TreeSupport::drawCircles(SliceDataStorage& storage, const std::vector<std::
}
{
- std::lock_guard<std::mutex> critical_section_support_max_layer_nr(critical_sections);
+ const std::lock_guard<std::mutex> lock(critical_section_progress);
if (!storage.support.supportLayers[layer_nr].support_infill_parts.empty() || !storage.support.supportLayers[layer_nr].support_roof.empty())
{
storage.support.layer_nr_max_filled_layer = std::max(storage.support.layer_nr_max_filled_layer, static_cast<int>(layer_nr));
}
- }
-
- ++completed;
-
- {
- std::lock_guard<std::mutex> critical_section_progress(critical_sections);
+ ++completed;
const double progress_contact_nodes = contact_nodes.size() * PROGRESS_WEIGHT_DROPDOWN;
const double progress_current = completed * PROGRESS_WEIGHT_AREAS;
const double progress_total = completed * PROGRESS_WEIGHT_AREAS;