Tweak to fix for thread concurency in looptri generation.
authorBastien Montagne <montagne29@wanadoo.fr>
Mon, 25 Sep 2017 07:56:02 +0000 (09:56 +0200)
committerBastien Montagne <montagne29@wanadoo.fr>
Mon, 25 Sep 2017 07:56:02 +0000 (09:56 +0200)
Even if pointer assignment may be atomic, it does not prevent reordering
and other nifty compiler tricks, we need a memory barrier to ensure not
only that transferring pointer from wip array to final one is atomic,
but also that all previous writing to memory are “flushed” to
(visible by) all CPUs...

Thanks @sergey for finding the potential (though quite unlikely) issue.

source/blender/blenkernel/intern/cdderivedmesh.c
source/blender/blenkernel/intern/editderivedmesh.c
source/blender/blenkernel/intern/subsurf_ccg.c

index 42ca4359a585d0da21756c2ba59a308e1348c024..4d94ebfed77b8ab7658f76e6282f1454c93289a4 100644 (file)
@@ -34,6 +34,8 @@
  *  \ingroup bke
  */
 
+#include "atomic_ops.h"
+
 #include "BLI_math.h"
 #include "BLI_edgehash.h"
 #include "BLI_utildefines.h"
@@ -1928,7 +1930,8 @@ void CDDM_recalc_looptri(DerivedMesh *dm)
                cddm->dm.looptris.array_wip);
 
        BLI_assert(cddm->dm.looptris.array == NULL);
-       SWAP(MLoopTri *, cddm->dm.looptris.array, cddm->dm.looptris.array_wip);
+       atomic_cas_z((size_t *)&cddm->dm.looptris.array, *(size_t *)&cddm->dm.looptris.array, *(size_t *)&cddm->dm.looptris.array_wip);
+       cddm->dm.looptris.array_wip = NULL;
 }
 
 static void cdDM_free_internal(CDDerivedMesh *cddm)
index 9f6884329885b1886bc2538e476d469e176f4c95..357420179ddf61004c9c949b55c97fbbd8f8dace 100644 (file)
@@ -41,6 +41,8 @@
  * is likely to be a little slow.
  */
 
+#include "atomic_ops.h"
+
 #include "BLI_math.h"
 #include "BLI_jitter.h"
 #include "BLI_bitmap.h"
@@ -662,7 +664,8 @@ static void emDM_recalcLoopTri(DerivedMesh *dm)
        }
 
        BLI_assert(dm->looptris.array == NULL);
-       SWAP(MLoopTri *, dm->looptris.array, dm->looptris.array_wip);
+       atomic_cas_z((size_t *)&dm->looptris.array, *(size_t *)&dm->looptris.array, *(size_t *)&dm->looptris.array_wip);
+       dm->looptris.array_wip = NULL;
 }
 
 static void emDM_foreachMappedVert(
index 27bbdf228d440412863c5e53984a541dace8dbf9..c580c04e0dfd2a3c0fa29f009e721d8e7b698426 100644 (file)
@@ -42,6 +42,8 @@
 #include <math.h>
 #include <float.h>
 
+#include "atomic_ops.h"
+
 #include "MEM_guardedalloc.h"
 
 #include "DNA_mesh_types.h"
@@ -4505,7 +4507,8 @@ static void ccgDM_recalcLoopTri(DerivedMesh *dm)
        }
 
        BLI_assert(dm->looptris.array == NULL);
-       SWAP(MLoopTri *, dm->looptris.array, dm->looptris.array_wip);
+       atomic_cas_z((size_t *)&dm->looptris.array, *(size_t *)&dm->looptris.array, *(size_t *)&dm->looptris.array_wip);
+       dm->looptris.array_wip = NULL;
 }
 
 static void ccgDM_calcNormals(DerivedMesh *dm)