Fix deadlocks in mesh modifier evaluation and particles

The recent task isolation changes missed two mutex locks that also need task
isolation.

Ref D11603, T89194
This commit is contained in:
Brecht Van Lommel 2021-06-21 18:44:40 +02:00
parent 47473bee34
commit 41af27c582
2 changed files with 19 additions and 5 deletions

View File

@ -42,6 +42,7 @@
#include "BLI_linklist.h"
#include "BLI_math.h"
#include "BLI_task.h"
#include "BLI_task.hh"
#include "BLI_utildefines.h"
#include "BLI_vector.hh"
@ -1463,10 +1464,14 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
BLI_assert(runtime->eval_mutex != nullptr);
BLI_mutex_lock((ThreadMutex *)runtime->eval_mutex);
if (runtime->mesh_eval == nullptr) {
mesh_final = BKE_mesh_copy_for_eval(mesh_input, true);
mesh_calc_modifier_final_normals(mesh_input, &final_datamask, sculpt_dyntopo, mesh_final);
mesh_calc_finalize(mesh_input, mesh_final);
runtime->mesh_eval = mesh_final;
/* Isolate since computing normals is multithreaded and we are holding a lock. */
blender::threading::isolate_task([&] {
mesh_final = BKE_mesh_copy_for_eval(mesh_input, true);
mesh_calc_modifier_final_normals(
mesh_input, &final_datamask, sculpt_dyntopo, mesh_final);
mesh_calc_finalize(mesh_input, mesh_final);
runtime->mesh_eval = mesh_final;
});
}
BLI_mutex_unlock((ThreadMutex *)runtime->eval_mutex);
}

View File

@ -1320,6 +1320,14 @@ void psys_get_pointcache_start_end(Scene *scene, ParticleSystem *psys, int *sfra
*efra = min_ii((int)(part->end + part->lifetime + 1.0f), max_ii(scene->r.pefra, scene->r.efra));
}
/* BVH tree balancing inside a mutex lock must be run in isolation. Balancing
* is multithreaded, and we do not want the current thread to start another task
* that may involve acquiring the same mutex lock that it is waiting for. */
static void bvhtree_balance_isolated(void *userdata)
{
BLI_bvhtree_balance((BVHTree *)userdata);
}
/************************************************/
/* Effectors */
/************************************************/
@ -1356,7 +1364,8 @@ static void psys_update_particle_bvhtree(ParticleSystem *psys, float cfra)
}
}
}
BLI_bvhtree_balance(psys->bvhtree);
BLI_task_isolate(bvhtree_balance_isolated, psys->bvhtree);
psys->bvhtree_frame = cfra;