forked from bartvdbraak/blender
Fix T38873: Crashing on undo of ocean modifier.
Issue of this bug is that most part of fftw is not thread safe, only compute-intensive fftw_execute & co are. Since smoke was affected by this issue as well, a global fftw mutex was added to BLI_threads. Audaspace also uses fftw in one of its readers (AUD_BandPassReader.cpp), but this is not an issue currently since this code is disabled in CMake/scons files. There was another threading issue with smoke, we need to copy dm used by emit_from_derivedmesh(), as it is modified by this func. Reviewers: sergey, brecht Reviewed By: brecht CC: brecht Differential Revision: https://developer.blender.org/D374
This commit is contained in:
parent
3eabe064ab
commit
f01d19431d
@ -846,6 +846,8 @@ void BKE_init_ocean(struct Ocean *o, int M, int N, float Lx, float Lz, float V,
|
|||||||
o->_fft_in = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_fft_in");
|
o->_fft_in = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_fft_in");
|
||||||
o->_htilda = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_htilda");
|
o->_htilda = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_htilda");
|
||||||
|
|
||||||
|
BLI_lock_thread(LOCK_FFTW);
|
||||||
|
|
||||||
if (o->_do_disp_y) {
|
if (o->_do_disp_y) {
|
||||||
o->_disp_y = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_disp_y");
|
o->_disp_y = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_disp_y");
|
||||||
o->_disp_y_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in, o->_disp_y, FFTW_ESTIMATE);
|
o->_disp_y_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in, o->_disp_y, FFTW_ESTIMATE);
|
||||||
@ -890,6 +892,8 @@ void BKE_init_ocean(struct Ocean *o, int M, int N, float Lx, float Lz, float V,
|
|||||||
o->_Jxz_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in_jxz, o->_Jxz, FFTW_ESTIMATE);
|
o->_Jxz_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in_jxz, o->_Jxz, FFTW_ESTIMATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BLI_unlock_thread(LOCK_FFTW);
|
||||||
|
|
||||||
BLI_rw_mutex_unlock(&o->oceanmutex);
|
BLI_rw_mutex_unlock(&o->oceanmutex);
|
||||||
|
|
||||||
set_height_normalize_factor(o);
|
set_height_normalize_factor(o);
|
||||||
@ -903,6 +907,8 @@ void BKE_free_ocean_data(struct Ocean *oc)
|
|||||||
|
|
||||||
BLI_rw_mutex_lock(&oc->oceanmutex, THREAD_LOCK_WRITE);
|
BLI_rw_mutex_lock(&oc->oceanmutex, THREAD_LOCK_WRITE);
|
||||||
|
|
||||||
|
BLI_lock_thread(LOCK_FFTW);
|
||||||
|
|
||||||
if (oc->_do_disp_y) {
|
if (oc->_do_disp_y) {
|
||||||
fftw_destroy_plan(oc->_disp_y_plan);
|
fftw_destroy_plan(oc->_disp_y_plan);
|
||||||
MEM_freeN(oc->_disp_y);
|
MEM_freeN(oc->_disp_y);
|
||||||
@ -939,6 +945,8 @@ void BKE_free_ocean_data(struct Ocean *oc)
|
|||||||
MEM_freeN(oc->_Jxz);
|
MEM_freeN(oc->_Jxz);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BLI_unlock_thread(LOCK_FFTW);
|
||||||
|
|
||||||
if (oc->_fft_in)
|
if (oc->_fft_in)
|
||||||
MEM_freeN(oc->_fft_in);
|
MEM_freeN(oc->_fft_in);
|
||||||
|
|
||||||
|
@ -207,7 +207,14 @@ void smoke_reallocate_highres_fluid(SmokeDomainSettings *sds, float dx, int res[
|
|||||||
sds->wt = NULL;
|
sds->wt = NULL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* smoke_turbulence_init uses non-threadsafe functions from fftw3 lib (like fftw_plan & co). */
|
||||||
|
BLI_lock_thread(LOCK_FFTW);
|
||||||
|
|
||||||
sds->wt = smoke_turbulence_init(res, sds->amplify + 1, sds->noise, BLI_temporary_dir(), use_fire, use_colors);
|
sds->wt = smoke_turbulence_init(res, sds->amplify + 1, sds->noise, BLI_temporary_dir(), use_fire, use_colors);
|
||||||
|
|
||||||
|
BLI_unlock_thread(LOCK_FFTW);
|
||||||
|
|
||||||
sds->res_wt[0] = res[0] * (sds->amplify + 1);
|
sds->res_wt[0] = res[0] * (sds->amplify + 1);
|
||||||
sds->res_wt[1] = res[1] * (sds->amplify + 1);
|
sds->res_wt[1] = res[1] * (sds->amplify + 1);
|
||||||
sds->res_wt[2] = res[2] * (sds->amplify + 1);
|
sds->res_wt[2] = res[2] * (sds->amplify + 1);
|
||||||
@ -1550,7 +1557,7 @@ static void emit_from_derivedmesh(Object *flow_ob, SmokeDomainSettings *sds, Smo
|
|||||||
{
|
{
|
||||||
if (!sfs->dm) return;
|
if (!sfs->dm) return;
|
||||||
{
|
{
|
||||||
DerivedMesh *dm = sfs->dm;
|
DerivedMesh *dm;
|
||||||
int defgrp_index = sfs->vgroup_density - 1;
|
int defgrp_index = sfs->vgroup_density - 1;
|
||||||
MDeformVert *dvert = NULL;
|
MDeformVert *dvert = NULL;
|
||||||
MVert *mvert = NULL;
|
MVert *mvert = NULL;
|
||||||
@ -1566,6 +1573,11 @@ static void emit_from_derivedmesh(Object *flow_ob, SmokeDomainSettings *sds, Smo
|
|||||||
int min[3], max[3], res[3];
|
int min[3], max[3], res[3];
|
||||||
int hires_multiplier = 1;
|
int hires_multiplier = 1;
|
||||||
|
|
||||||
|
/* copy derivedmesh for thread safety because we modify it,
|
||||||
|
* main issue is its VertArray being modified, then replaced and freed
|
||||||
|
*/
|
||||||
|
dm = CDDM_copy(sfs->dm);
|
||||||
|
|
||||||
CDDM_calc_normals(dm);
|
CDDM_calc_normals(dm);
|
||||||
mvert = dm->getVertArray(dm);
|
mvert = dm->getVertArray(dm);
|
||||||
mvert_orig = dm->dupVertArray(dm); /* copy original mvert and restore when done */
|
mvert_orig = dm->dupVertArray(dm); /* copy original mvert and restore when done */
|
||||||
|
@ -88,6 +88,7 @@ int BLI_system_num_threads_override_get(void);
|
|||||||
#define LOCK_NODES 6
|
#define LOCK_NODES 6
|
||||||
#define LOCK_MOVIECLIP 7
|
#define LOCK_MOVIECLIP 7
|
||||||
#define LOCK_COLORMANAGE 8
|
#define LOCK_COLORMANAGE 8
|
||||||
|
#define LOCK_FFTW 9
|
||||||
|
|
||||||
void BLI_lock_thread(int type);
|
void BLI_lock_thread(int type);
|
||||||
void BLI_unlock_thread(int type);
|
void BLI_unlock_thread(int type);
|
||||||
|
@ -121,6 +121,7 @@ static pthread_mutex_t _opengl_lock = PTHREAD_MUTEX_INITIALIZER;
|
|||||||
static pthread_mutex_t _nodes_lock = PTHREAD_MUTEX_INITIALIZER;
|
static pthread_mutex_t _nodes_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
static pthread_mutex_t _movieclip_lock = PTHREAD_MUTEX_INITIALIZER;
|
static pthread_mutex_t _movieclip_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
static pthread_mutex_t _colormanage_lock = PTHREAD_MUTEX_INITIALIZER;
|
static pthread_mutex_t _colormanage_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
static pthread_mutex_t _fftw_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
static pthread_t mainid;
|
static pthread_t mainid;
|
||||||
static int thread_levels = 0; /* threads can be invoked inside threads */
|
static int thread_levels = 0; /* threads can be invoked inside threads */
|
||||||
static int num_threads_override = 0;
|
static int num_threads_override = 0;
|
||||||
@ -399,6 +400,8 @@ void BLI_lock_thread(int type)
|
|||||||
pthread_mutex_lock(&_movieclip_lock);
|
pthread_mutex_lock(&_movieclip_lock);
|
||||||
else if (type == LOCK_COLORMANAGE)
|
else if (type == LOCK_COLORMANAGE)
|
||||||
pthread_mutex_lock(&_colormanage_lock);
|
pthread_mutex_lock(&_colormanage_lock);
|
||||||
|
else if (type == LOCK_FFTW)
|
||||||
|
pthread_mutex_lock(&_fftw_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BLI_unlock_thread(int type)
|
void BLI_unlock_thread(int type)
|
||||||
@ -421,6 +424,8 @@ void BLI_unlock_thread(int type)
|
|||||||
pthread_mutex_unlock(&_movieclip_lock);
|
pthread_mutex_unlock(&_movieclip_lock);
|
||||||
else if (type == LOCK_COLORMANAGE)
|
else if (type == LOCK_COLORMANAGE)
|
||||||
pthread_mutex_unlock(&_colormanage_lock);
|
pthread_mutex_unlock(&_colormanage_lock);
|
||||||
|
else if (type == LOCK_FFTW)
|
||||||
|
pthread_mutex_unlock(&_fftw_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Mutex Locks */
|
/* Mutex Locks */
|
||||||
|
Loading…
Reference in New Issue
Block a user