[Bf-blender-cvs] [5de8134abc1] sculpt-dev: Sculpt: experiment with lock-free mempools and fine grained locks.

Joseph Eagar noreply at git.blender.org
Thu Oct 21 02:30:10 CEST 2021


Commit: 5de8134abc1814b738805877dab2d03530f21615
Author: Joseph Eagar
Date:   Wed Oct 20 14:14:12 2021 -0700
Branches: sculpt-dev
https://developer.blender.org/rB5de8134abc1814b738805877dab2d03530f21615

Sculpt: experiment with lock-free mempools
        and fine grained locks.

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

M	intern/guardedalloc/MEM_guardedalloc.h
M	intern/guardedalloc/intern/mallocn.c
M	intern/guardedalloc/intern/mallocn_guarded_impl.c
M	intern/guardedalloc/intern/mallocn_intern.h
M	intern/guardedalloc/intern/mallocn_lockfree_impl.c
M	release/datafiles/locale
M	source/blender/blenkernel/intern/colortools.c
M	source/blender/blenkernel/intern/dyntopo.c
A	source/blender/blenlib/BLI_mempool_lockfree.h
M	source/blender/blenlib/CMakeLists.txt
A	source/blender/blenlib/intern/lockfree_mempool.cc
M	source/blender/blentranslation/msgfmt/msgfmt.c
M	source/blender/editors/sculpt_paint/paint_mask.c
M	source/blender/editors/sculpt_paint/sculpt.c
M	source/blender/editors/sculpt_paint/sculpt_dyntopo.c

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

diff --git a/intern/guardedalloc/MEM_guardedalloc.h b/intern/guardedalloc/MEM_guardedalloc.h
index 713b1fac788..120fae215c3 100644
--- a/intern/guardedalloc/MEM_guardedalloc.h
+++ b/intern/guardedalloc/MEM_guardedalloc.h
@@ -81,6 +81,12 @@ extern short (*MEM_testN)(void *vmemh);
  * newly allocated block. */
 extern void *(*MEM_dupallocN)(const void *vmemh) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT;
 
+/**
+ * Duplicates a block of memory, and returns a pointer to the
+ * newly allocated block. */
+extern void *(*MEM_dupallocN_id)(const void *vmemh,
+                                 const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT;
+
 /**
  * Reallocates a block of memory, and returns pointer to the newly
  * allocated block, the old one is freed. this is not as optimized
@@ -253,6 +259,8 @@ void MEM_use_lockfree_allocator(void);
  * NOTE: The switch between allocator types can only happen before any allocation did happen. */
 void MEM_use_guarded_allocator(void);
 
+#define MEM_dupallocN(vmemh) MEM_dupallocN_id(vmemh, __func__)
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
diff --git a/intern/guardedalloc/intern/mallocn.c b/intern/guardedalloc/intern/mallocn.c
index 261a23a1196..1902d10f494 100644
--- a/intern/guardedalloc/intern/mallocn.c
+++ b/intern/guardedalloc/intern/mallocn.c
@@ -40,6 +40,7 @@ const char *malloc_conf = "background_thread:true,dirty_decay_ms:4000";
 size_t (*MEM_allocN_len)(const void *vmemh) = MEM_lockfree_allocN_len;
 void (*MEM_freeN)(void *vmemh) = MEM_lockfree_freeN;
 void *(*MEM_dupallocN)(const void *vmemh) = MEM_lockfree_dupallocN;
+void *(*MEM_dupallocN_id)(const void *vmemh) = MEM_lockfree_dupallocN_id;
 void *(*MEM_reallocN_id)(void *vmemh, size_t len, const char *str) = MEM_lockfree_reallocN_id;
 void *(*MEM_recallocN_id)(void *vmemh, size_t len, const char *str) = MEM_lockfree_recallocN_id;
 void *(*MEM_callocN)(size_t len, const char *str) = MEM_lockfree_callocN;
@@ -121,6 +122,7 @@ void MEM_use_lockfree_allocator(void)
   MEM_allocN_len = MEM_lockfree_allocN_len;
   MEM_freeN = MEM_lockfree_freeN;
   MEM_dupallocN = MEM_lockfree_dupallocN;
+  MEM_dupallocN_id = MEM_lockfree_dupallocN_id;
   MEM_reallocN_id = MEM_lockfree_reallocN_id;
   MEM_recallocN_id = MEM_lockfree_recallocN_id;
   MEM_callocN = MEM_lockfree_callocN;
@@ -152,6 +154,7 @@ void MEM_use_guarded_allocator(void)
   MEM_allocN_len = MEM_guarded_allocN_len;
   MEM_freeN = MEM_guarded_freeN;
   MEM_dupallocN = MEM_guarded_dupallocN;
+  MEM_dupallocN_id = MEM_guarded_dupallocN_id;
   MEM_reallocN_id = MEM_guarded_reallocN_id;
   MEM_recallocN_id = MEM_guarded_recallocN_id;
   MEM_callocN = MEM_guarded_callocN;
diff --git a/intern/guardedalloc/intern/mallocn_guarded_impl.c b/intern/guardedalloc/intern/mallocn_guarded_impl.c
index 3baa8e1a689..decb6bcf3cf 100644
--- a/intern/guardedalloc/intern/mallocn_guarded_impl.c
+++ b/intern/guardedalloc/intern/mallocn_guarded_impl.c
@@ -303,6 +303,31 @@ void *MEM_guarded_dupallocN(const void *vmemh)
   return newp;
 }
 
+void *MEM_guarded_dupallocN_id(const void *vmemh, const char *str)
+{
+  void *newp = NULL;
+
+  if (vmemh) {
+    const MemHead *memh = vmemh;
+    memh--;
+
+    if (LIKELY(memh->alignment == 0)) {
+      newp = MEM_guarded_mallocN(memh->len, str);
+    }
+    else {
+      newp = MEM_guarded_mallocN_aligned(memh->len, (size_t)memh->alignment, str);
+    }
+
+    if (newp == NULL) {
+      return NULL;
+    }
+
+    memcpy(newp, vmemh, memh->len);
+  }
+
+  return newp;
+}
+
 void *MEM_guarded_reallocN_id(void *vmemh, size_t len, const char *str)
 {
   void *newp = NULL;
@@ -408,7 +433,7 @@ static void print_memhead_backtrace(MemHead *memh)
   (void)memh; /* Ignored. */
 }
 #  endif /* defined(__linux__) || defined(__APPLE__) */
-#endif /* DEBUG_BACKTRACE */
+#endif   /* DEBUG_BACKTRACE */
 
 static void make_memhead_header(MemHead *memh, size_t len, const char *str)
 {
diff --git a/intern/guardedalloc/intern/mallocn_intern.h b/intern/guardedalloc/intern/mallocn_intern.h
index e4bd3d533a3..7f20f798999 100644
--- a/intern/guardedalloc/intern/mallocn_intern.h
+++ b/intern/guardedalloc/intern/mallocn_intern.h
@@ -110,6 +110,8 @@ extern char free_after_leak_detection_message[];
 size_t MEM_lockfree_allocN_len(const void *vmemh) ATTR_WARN_UNUSED_RESULT;
 void MEM_lockfree_freeN(void *vmemh);
 void *MEM_lockfree_dupallocN(const void *vmemh) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
+void *MEM_lockfree_dupallocN_id(const void *vmemh,
+                                const char *str) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
 void *MEM_lockfree_reallocN_id(void *vmemh,
                                size_t len,
                                const char *str) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
@@ -153,6 +155,8 @@ const char *MEM_lockfree_name_ptr(void *vmemh);
 size_t MEM_guarded_allocN_len(const void *vmemh) ATTR_WARN_UNUSED_RESULT;
 void MEM_guarded_freeN(void *vmemh);
 void *MEM_guarded_dupallocN(const void *vmemh) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
+void *MEM_guarded_dupallocN_id(const void *vmemh,
+                               const char *str) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
 void *MEM_guarded_reallocN_id(void *vmemh,
                               size_t len,
                               const char *str) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
diff --git a/intern/guardedalloc/intern/mallocn_lockfree_impl.c b/intern/guardedalloc/intern/mallocn_lockfree_impl.c
index fbde663440a..332c6636ecc 100644
--- a/intern/guardedalloc/intern/mallocn_lockfree_impl.c
+++ b/intern/guardedalloc/intern/mallocn_lockfree_impl.c
@@ -29,8 +29,8 @@
 #include "MEM_guardedalloc.h"
 
 /* to ensure strict conversions */
-#include "../../source/blender/blenlib/BLI_strict_flags.h"
 #include "../../source/blender/blenlib/BLI_asan.h"
+#include "../../source/blender/blenlib/BLI_strict_flags.h"
 
 #include "atomic_ops.h"
 #include "mallocn_intern.h"
@@ -167,6 +167,29 @@ void *MEM_lockfree_dupallocN(const void *vmemh)
   return newp;
 }
 
+void *MEM_lockfree_dupallocN_id(const void *vmemh, const char *str)
+{
+  void *newp = NULL;
+  if (vmemh) {
+    MemHead *memh = MEMHEAD_FROM_PTR(vmemh);
+    const size_t prev_size = MEM_lockfree_allocN_len(vmemh);
+
+    MEM_UNPOISON_MEMHEAD(vmemh);
+
+    if (UNLIKELY(MEMHEAD_IS_ALIGNED(memh))) {
+      MemHeadAligned *memh_aligned = MEMHEAD_ALIGNED_FROM_PTR(vmemh);
+      newp = MEM_lockfree_mallocN_aligned(prev_size, (size_t)memh_aligned->alignment, str);
+    }
+    else {
+      newp = MEM_lockfree_mallocN(prev_size, str);
+    }
+
+    MEM_POISON_MEMHEAD(vmemh);
+    memcpy(newp, vmemh, prev_size);
+  }
+  return newp;
+}
+
 void *MEM_lockfree_reallocN_id(void *vmemh, size_t len, const char *str)
 {
   void *newp = NULL;
diff --git a/release/datafiles/locale b/release/datafiles/locale
index 75e46177f36..80d9e7ee122 160000
--- a/release/datafiles/locale
+++ b/release/datafiles/locale
@@ -1 +1 @@
-Subproject commit 75e46177f36a49ad36b917e641ee1586ddef7092
+Subproject commit 80d9e7ee122c626cbbcd1da554683bce79f8d3df
diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c
index d481a7a9162..32cec26974c 100644
--- a/source/blender/blenkernel/intern/colortools.c
+++ b/source/blender/blenkernel/intern/colortools.c
@@ -163,6 +163,15 @@ void BKE_curvemapping_copy_data_tag_ex(CurveMapping *target,
   }
 }
 
+static void *debug_dupalloc_id(const void *mem, const char *id)
+{
+  int len = MEM_allocN_len(mem);
+  void *cpy = MEM_mallocN(len, id);
+  memcpy(cpy, mem, len);
+
+  return cpy;
+}
+
 void BKE_curvemapping_copy_data(CurveMapping *target, const CurveMapping *cumap)
 {
   int a;
@@ -177,13 +186,14 @@ void BKE_curvemapping_copy_data(CurveMapping *target, const CurveMapping *cumap)
 
   for (a = 0; a < CM_TOT; a++) {
     if (cumap->cm[a].curve) {
-      target->cm[a].curve = MEM_dupallocN(cumap->cm[a].curve);
+      target->cm[a].curve = debug_dupalloc_id(cumap->cm[a].curve, "curvemapping.curve");
     }
     if (cumap->cm[a].table) {
-      target->cm[a].table = MEM_dupallocN(cumap->cm[a].table);
+      target->cm[a].table = debug_dupalloc_id(cumap->cm[a].table, "curvemapping.table");
     }
     if (cumap->cm[a].premultable) {
-      target->cm[a].premultable = MEM_dupallocN(cumap->cm[a].premultable);
+      target->cm[a].premultable = debug_dupalloc_id(cumap->cm[a].premultable,
+                                                    "curvemapping.premultable");
     }
   }
 }
@@ -191,7 +201,7 @@ void BKE_curvemapping_copy_data(CurveMapping *target, const CurveMapping *cumap)
 CurveMapping *BKE_curvemapping_copy(const CurveMapping *cumap)
 {
   if (cumap) {
-    CurveMapping *cumapn = MEM_dupallocN(cumap);
+    CurveMapping *cumapn = debug_dupalloc_id(cumap, "CurveMapping");
     BKE_curvemapping_copy_data(cumapn, cumap);
     cumapn->flag &= ~CUMA_PART_OF_CACHE;
     return cumapn;
diff --git a/source/blender/blenkernel/intern/dyntopo.c b/source/blender/blenkernel/intern/dyntopo.c
index dd076f26bb9..f59a93e9cbd 100644
--- a/source/blender/blenkernel/intern/dyntopo.c
+++ b/source/blender/blenkernel/intern/dyntopo.c
@@ -34,6 +34,7 @@
 
 #include <stdio.h>
 
+#define DYNTOPO_EDGE_LOCKS
 //#define DYNTOPO_REPORT
 //#define WITH_ADAPTIVE_CURVATURE
 
@@ -190,6 +191,169 @@ void bmesh_radial_loop_append(BMEdge *e, BMLoop *l);
 void bm_kill_only_edge(BMesh *bm, BMEdge *e);
 void bm_kill_only_loop(BMesh *bm, BMLoop *l);
 void bm_kill_only_face(BMesh *bm, BMFace *f);
+static bool bm_elem_is_free(BMElem *elem, int htype);
+
+extern char dyntopop_node_idx_layer_id[];
+extern char dyntopop_faces_areas_layer_id[];
+
+#ifdef DYNTOPO_EDGE_LOCKS
+
+char *cdlayer_lock_attr_name = "__bm_lock";
+
+static int cdlayer_lock_begin(PBVH *pbvh, BMesh *bm)
+{
+  int idx = CustomData_get_named_layer_index(&bm->edata, CD_PROP_INT32, cdlayer_lock_attr_name);
+
+  if (idx == -1) {
+    BM_data_layer_add_named(bm, &bm->edata, CD_PROP_INT32, cdlayer_lock_attr_name);
+
+    idx = CustomData_get_named_layer_index(&bm->edata, CD_PROP_INT32, cdlayer_lock_attr_name);
+    bm->vdata.layers[idx].flag |= CD_FLAG_TEMPORARY | CD_FLAG_ELEM_NOCOPY | CD_FLAG_ELEM_NOINTERP;
+
+    pbvh->cd_vert_node_offset = CustomData_get_named_layer_index(
+        &pbvh->bm->vdata, CD_PR

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list