Tweak to fix for thread concurency in looptri generation.
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.
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user