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);