Commit: f01d19431d0e2a14a007d5480e805b99dc933169
Author: Bastien Montagne
Date:   Sat Mar 1 20:46:58 2014 +0100
https://developer.blender.org/rBf01d19431d0e2a14a007d5480e805b99dc933169

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

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

M       source/blender/blenkernel/intern/ocean.c
M       source/blender/blenkernel/intern/smoke.c
M       source/blender/blenlib/BLI_threads.h
M       source/blender/blenlib/intern/threads.c

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

diff --git a/source/blender/blenkernel/intern/ocean.c 
b/source/blender/blenkernel/intern/ocean.c
index c1e4336..3458f14 100644
--- a/source/blender/blenkernel/intern/ocean.c
+++ b/source/blender/blenkernel/intern/ocean.c
@@ -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->_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) {
                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);
@@ -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);
        }
 
+       BLI_unlock_thread(LOCK_FFTW);
+
        BLI_rw_mutex_unlock(&o->oceanmutex);
 
        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_lock_thread(LOCK_FFTW);
+
        if (oc->_do_disp_y) {
                fftw_destroy_plan(oc->_disp_y_plan);
                MEM_freeN(oc->_disp_y);
@@ -939,6 +945,8 @@ void BKE_free_ocean_data(struct Ocean *oc)
                MEM_freeN(oc->_Jxz);
        }
 
+       BLI_unlock_thread(LOCK_FFTW);
+
        if (oc->_fft_in)
                MEM_freeN(oc->_fft_in);
 
diff --git a/source/blender/blenkernel/intern/smoke.c 
b/source/blender/blenkernel/intern/smoke.c
index 61d9ea9..0ec277a 100644
--- a/source/blender/blenkernel/intern/smoke.c
+++ b/source/blender/blenkernel/intern/smoke.c
@@ -207,7 +207,14 @@ void smoke_reallocate_highres_fluid(SmokeDomainSettings 
*sds, float dx, int res[
                sds->wt = NULL;
                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);
+
+       BLI_unlock_thread(LOCK_FFTW);
+
        sds->res_wt[0] = res[0] * (sds->amplify + 1);
        sds->res_wt[1] = res[1] * (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;
        {
-               DerivedMesh *dm = sfs->dm;
+               DerivedMesh *dm;
                int defgrp_index = sfs->vgroup_density - 1;
                MDeformVert *dvert = 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 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);
                mvert = dm->getVertArray(dm);
                mvert_orig = dm->dupVertArray(dm);  /* copy original mvert and 
restore when done */
diff --git a/source/blender/blenlib/BLI_threads.h 
b/source/blender/blenlib/BLI_threads.h
index 3ccfcc0..62eadb8 100644
--- a/source/blender/blenlib/BLI_threads.h
+++ b/source/blender/blenlib/BLI_threads.h
@@ -88,6 +88,7 @@ int     BLI_system_num_threads_override_get(void);
 #define LOCK_NODES      6
 #define LOCK_MOVIECLIP  7
 #define LOCK_COLORMANAGE 8
+#define LOCK_FFTW       9
 
 void    BLI_lock_thread(int type);
 void    BLI_unlock_thread(int type);
diff --git a/source/blender/blenlib/intern/threads.c 
b/source/blender/blenlib/intern/threads.c
index c9f4e9d..ded2fd7 100644
--- a/source/blender/blenlib/intern/threads.c
+++ b/source/blender/blenlib/intern/threads.c
@@ -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 _movieclip_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 int thread_levels = 0;  /* threads can be invoked inside threads */
 static int num_threads_override = 0;
@@ -399,6 +400,8 @@ void BLI_lock_thread(int type)
                pthread_mutex_lock(&_movieclip_lock);
        else if (type == LOCK_COLORMANAGE)
                pthread_mutex_lock(&_colormanage_lock);
+       else if (type == LOCK_FFTW)
+               pthread_mutex_lock(&_fftw_lock);
 }
 
 void BLI_unlock_thread(int type)
@@ -421,6 +424,8 @@ void BLI_unlock_thread(int type)
                pthread_mutex_unlock(&_movieclip_lock);
        else if (type == LOCK_COLORMANAGE)
                pthread_mutex_unlock(&_colormanage_lock);
+       else if (type == LOCK_FFTW)
+               pthread_mutex_unlock(&_fftw_lock);
 }
 
 /* Mutex Locks */

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to