diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index 12d7409..18e0ec8 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -169,6 +169,8 @@ static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels,
CCGAllocatorIFC allocatorIFC;
CCGAllocatorHDL allocator = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 16), "subsurf arena");
+ BLI_memarena_set_threadsafe((MemArena *)allocator);
+
allocatorIFC.alloc = arena_alloc;
allocatorIFC.realloc = arena_realloc;
allocatorIFC.free = arena_free;
diff --git a/source/blender/blenlib/BLI_memarena.h b/source/blender/blenlib/BLI_memarena.h
index 8d5a765..a063445 100644
--- a/source/blender/blenlib/BLI_memarena.h
+++ b/source/blender/blenlib/BLI_memarena.h
@@ -57,6 +57,8 @@ void BLI_memarena_free(struct MemArena *ma) ATTR_NONNULL(1);
void BLI_memarena_use_malloc(struct MemArena *ma) ATTR_NONNULL(1);
void BLI_memarena_use_calloc(struct MemArena *ma) ATTR_NONNULL(1);
void BLI_memarena_use_align(struct MemArena *ma, const size_t align) ATTR_NONNULL(1);
+void BLI_memarena_set_threadsafe(struct MemArena *ma);
+void BLI_memarena_clear_threadsafe(struct MemArena *ma);
void *BLI_memarena_alloc(struct MemArena *ma, size_t size) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_ALLOC_SIZE(2);
void *BLI_memarena_calloc(struct MemArena *ma, size_t size) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_ALLOC_SIZE(2);
diff --git a/source/blender/blenlib/intern/BLI_memarena.c b/source/blender/blenlib/intern/BLI_memarena.c
index dd0997c..08dd545 100644
--- a/source/blender/blenlib/intern/BLI_memarena.c
+++ b/source/blender/blenlib/intern/BLI_memarena.c
@@ -38,6 +38,7 @@
#include "BLI_utildefines.h"
#include "BLI_memarena.h"
#include "BLI_linklist.h"
+#include "BLI_threads.h"
#include "BLI_strict_flags.h"
#ifdef WITH_MEM_VALGRIND
@@ -53,6 +54,8 @@ struct MemArena {
size_t align;
bool use_calloc;
+
+ SpinLock *spin_lock, spin_lock_;
};
MemArena *BLI_memarena_new(const size_t bufsize, const char *name)
@@ -66,6 +69,8 @@ MemArena *BLI_memarena_new(const size_t bufsize, const char *name)
VALGRIND_CREATE_MEMPOOL(ma, 0, false);
#endif
+ ma->spin_lock = NULL;
+
return ma;
}
@@ -85,6 +90,22 @@ void BLI_memarena_use_align(struct MemArena *ma, const size_t align)
ma->align = align;
}
+void BLI_memarena_set_threadsafe(MemArena *ma)
+{
+ if (!ma->spin_lock) {
+ BLI_spin_init(&ma->spin_lock_);
+ ma->spin_lock = &ma->spin_lock_;
+ }
+}
+
+void BLI_memarena_clear_threadsafe(MemArena *ma)
+{
+ if (ma->spin_lock) {
+ ma->spin_lock = NULL;
+ BLI_spin_end(&ma->spin_lock_);
+ }
+}
+
void BLI_memarena_free(MemArena *ma)
{
BLI_linklist_freeN(ma->bufs);
@@ -93,6 +114,8 @@ void BLI_memarena_free(MemArena *ma)
VALGRIND_DESTROY_MEMPOOL(ma);
#endif
+ BLI_memarena_clear_threadsafe(ma);
+
MEM_freeN(ma);
}
@@ -117,6 +140,10 @@ void *BLI_memarena_alloc(MemArena *ma, size_t size)
* size up to multiple of 8 */
size = PADUP(size, ma->align);
+ if (ma->spin_lock) {
+ BLI_spin_lock(ma->spin_lock);
+ }
+
if (UNLIKELY(size > ma->cursize)) {
if (size > ma->bufsize - (ma->align - 1)) {
ma->cursize = PADUP(size + 1, ma->align);
@@ -138,6 +165,10 @@ void *BLI_memarena_alloc(MemArena *ma, size_t size)
VALGRIND_MEMPOOL_ALLOC(ma, ptr, size);
#endif
+ if (ma->spin_lock) {
+ BLI_spin_unlock(ma->spin_lock);
+ }
+
return ptr;
}
diff --git a/source/blender/modifiers/intern/MOD_meshdeform.c b/source/blender/modifiers/intern/MOD_meshdeform.c
index 584b5b5..364146f 100644
--- a/source/blender/modifiers/intern/MOD_meshdeform.c
+++ b/source/blender/modifiers/intern/MOD_meshdeform.c
@@ -415,6 +415,24 @@ static void deformVerts(ModifierData *md, Object *ob,
{
DerivedMesh *dm = get_dm(ob, NULL, derivedData, NULL, false, false);
+
+ if (0) {
+ #include "BLI_memarena.h"
+ #include "PIL_time_utildefines.h"
+ MemArena *ma = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
+ int i = 1000000;
+
+ BLI_memarena_set_threadsafe(ma);
+
+ TIMEIT_START(foo);
+ while (i--) {
+ BLI_memarena_alloc(ma, sizeof(int));
+ }
+ TIMEIT_END(foo);
+
+ BLI_memarena_free(ma);
+ }
+
modifier_vgroup_cache(md, vertexCos); /* if next modifier needs original vertices */
meshdeformModifier_do(md, ob, dm, vertexCos, numVerts);