[Bf-blender-cvs] [dca36a8ec92] blender-v2.91-release: Fix T82769: remove thread local data from PTCacheMem

Jacques Lucke noreply at git.blender.org
Thu Nov 19 19:15:36 CET 2020


Commit: dca36a8ec922bcce6bc4882cd6cba52792ed56ee
Author: Jacques Lucke
Date:   Thu Nov 19 19:09:24 2020 +0100
Branches: blender-v2.91-release
https://developer.blender.org/rBdca36a8ec922bcce6bc4882cd6cba52792ed56ee

Fix T82769: remove thread local data from PTCacheMem

The issue was that the same point cache was read by multiple
threads at the same time (the same object was evaluated for
render and for the viewport).
Both threads incremented PTCacheMem->cur which lead to the crash.

The fix is to remove the PTCacheMem->cur and store it on the
stack instead. This way every thread has its own cur.

Reviewers: brecht

Differential Revision: https://developer.blender.org/D9606

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

M	source/blender/blenkernel/BKE_pointcache.h
M	source/blender/blenkernel/intern/pointcache.c
M	source/blender/editors/physics/particle_edit.c
M	source/blender/editors/physics/particle_edit_undo.c
M	source/blender/makesdna/DNA_pointcache_types.h

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

diff --git a/source/blender/blenkernel/BKE_pointcache.h b/source/blender/blenkernel/BKE_pointcache.h
index f8e04b75b3d..9285a0a30eb 100644
--- a/source/blender/blenkernel/BKE_pointcache.h
+++ b/source/blender/blenkernel/BKE_pointcache.h
@@ -322,9 +322,11 @@ int BKE_ptcache_data_size(int data_type);
 int BKE_ptcache_mem_index_find(struct PTCacheMem *pm, unsigned int index);
 
 /* Memory cache read/write helpers. */
-void BKE_ptcache_mem_pointers_init(struct PTCacheMem *pm);
-void BKE_ptcache_mem_pointers_incr(struct PTCacheMem *pm);
-int BKE_ptcache_mem_pointers_seek(int point_index, struct PTCacheMem *pm);
+void BKE_ptcache_mem_pointers_init(struct PTCacheMem *pm, void *cur[BPHYS_TOT_DATA]);
+void BKE_ptcache_mem_pointers_incr(void *cur[BPHYS_TOT_DATA]);
+int BKE_ptcache_mem_pointers_seek(int point_index,
+                                  struct PTCacheMem *pm,
+                                  void *cur[BPHYS_TOT_DATA]);
 
 /* Main cache reading call. */
 int BKE_ptcache_read(PTCacheID *pid, float cfra, bool no_extrapolate_old);
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index 7c8527a8702..e87f037281d 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -1727,27 +1727,27 @@ int BKE_ptcache_mem_index_find(PTCacheMem *pm, unsigned int index)
   return (index < pm->totpoint ? index : -1);
 }
 
-void BKE_ptcache_mem_pointers_init(PTCacheMem *pm)
+void BKE_ptcache_mem_pointers_init(PTCacheMem *pm, void *cur[BPHYS_TOT_DATA])
 {
   int data_types = pm->data_types;
   int i;
 
   for (i = 0; i < BPHYS_TOT_DATA; i++) {
-    pm->cur[i] = ((data_types & (1 << i)) ? pm->data[i] : NULL);
+    cur[i] = ((data_types & (1 << i)) ? pm->data[i] : NULL);
   }
 }
 
-void BKE_ptcache_mem_pointers_incr(PTCacheMem *pm)
+void BKE_ptcache_mem_pointers_incr(void *cur[BPHYS_TOT_DATA])
 {
   int i;
 
   for (i = 0; i < BPHYS_TOT_DATA; i++) {
-    if (pm->cur[i]) {
-      pm->cur[i] = (char *)pm->cur[i] + ptcache_data_size[i];
+    if (cur[i]) {
+      cur[i] = (char *)cur[i] + ptcache_data_size[i];
     }
   }
 }
-int BKE_ptcache_mem_pointers_seek(int point_index, PTCacheMem *pm)
+int BKE_ptcache_mem_pointers_seek(int point_index, PTCacheMem *pm, void *cur[BPHYS_TOT_DATA])
 {
   int data_types = pm->data_types;
   int i, index = BKE_ptcache_mem_index_find(pm, point_index);
@@ -1762,7 +1762,7 @@ int BKE_ptcache_mem_pointers_seek(int point_index, PTCacheMem *pm)
   }
 
   for (i = 0; i < BPHYS_TOT_DATA; i++) {
-    pm->cur[i] = data_types & (1 << i) ? (char *)pm->data[i] + index * ptcache_data_size[i] : NULL;
+    cur[i] = data_types & (1 << i) ? (char *)pm->data[i] + index * ptcache_data_size[i] : NULL;
   }
 
   return 1;
@@ -1932,7 +1932,8 @@ static PTCacheMem *ptcache_disk_frame_to_mem(PTCacheID *pid, int cfra)
       }
     }
     else {
-      BKE_ptcache_mem_pointers_init(pm);
+      void *cur[BPHYS_TOT_DATA];
+      BKE_ptcache_mem_pointers_init(pm, cur);
       ptcache_file_pointers_init(pf);
 
       for (i = 0; i < pm->totpoint; i++) {
@@ -1940,8 +1941,8 @@ static PTCacheMem *ptcache_disk_frame_to_mem(PTCacheID *pid, int cfra)
           error = 1;
           break;
         }
-        ptcache_data_copy(pf->cur, pm->cur);
-        BKE_ptcache_mem_pointers_incr(pm);
+        ptcache_data_copy(pf->cur, cur);
+        BKE_ptcache_mem_pointers_incr(cur);
       }
     }
   }
@@ -2033,16 +2034,17 @@ static int ptcache_mem_frame_to_disk(PTCacheID *pid, PTCacheMem *pm)
       }
     }
     else {
-      BKE_ptcache_mem_pointers_init(pm);
+      void *cur[BPHYS_TOT_DATA];
+      BKE_ptcache_mem_pointers_init(pm, cur);
       ptcache_file_pointers_init(pf);
 
       for (i = 0; i < pm->totpoint; i++) {
-        ptcache_data_copy(pm->cur, pf->cur);
+        ptcache_data_copy(cur, pf->cur);
         if (!ptcache_file_data_write(pf)) {
           error = 1;
           break;
         }
-        BKE_ptcache_mem_pointers_incr(pm);
+        BKE_ptcache_mem_pointers_incr(cur);
       }
     }
   }
@@ -2160,16 +2162,17 @@ static int ptcache_read(PTCacheID *pid, int cfra)
       }
     }
 
-    BKE_ptcache_mem_pointers_init(pm);
+    void *cur[BPHYS_TOT_DATA];
+    BKE_ptcache_mem_pointers_init(pm, cur);
 
     for (i = 0; i < totpoint; i++) {
       if (pm->data_types & (1 << BPHYS_DATA_INDEX)) {
-        index = pm->cur[BPHYS_DATA_INDEX];
+        index = cur[BPHYS_DATA_INDEX];
       }
 
-      pid->read_point(*index, pid->calldata, pm->cur, (float)pm->frame, NULL);
+      pid->read_point(*index, pid->calldata, cur, (float)pm->frame, NULL);
 
-      BKE_ptcache_mem_pointers_incr(pm);
+      BKE_ptcache_mem_pointers_incr(cur);
     }
 
     if (pid->read_extra_data && pm->extradata.first) {
@@ -2216,16 +2219,16 @@ static int ptcache_interpolate(PTCacheID *pid, float cfra, int cfra1, int cfra2)
       }
     }
 
-    BKE_ptcache_mem_pointers_init(pm);
+    void *cur[BPHYS_TOT_DATA];
+    BKE_ptcache_mem_pointers_init(pm, cur);
 
     for (i = 0; i < totpoint; i++) {
       if (pm->data_types & (1 << BPHYS_DATA_INDEX)) {
-        index = pm->cur[BPHYS_DATA_INDEX];
+        index = cur[BPHYS_DATA_INDEX];
       }
 
-      pid->interpolate_point(
-          *index, pid->calldata, pm->cur, cfra, (float)cfra1, (float)cfra2, NULL);
-      BKE_ptcache_mem_pointers_incr(pm);
+      pid->interpolate_point(*index, pid->calldata, cur, cfra, (float)cfra1, (float)cfra2, NULL);
+      BKE_ptcache_mem_pointers_incr(cur);
     }
 
     if (pid->interpolate_extra_data && pm->extradata.first) {
@@ -2389,7 +2392,8 @@ static int ptcache_write(PTCacheID *pid, int cfra, int overwrite)
   pm->data_types = cfra ? pid->data_types : pid->info_types;
 
   ptcache_data_alloc(pm);
-  BKE_ptcache_mem_pointers_init(pm);
+  void *cur[BPHYS_TOT_DATA];
+  BKE_ptcache_mem_pointers_init(pm, cur);
 
   if (overwrite) {
     if (cache->flag & PTCACHE_DISK_CACHE) {
@@ -2408,13 +2412,14 @@ static int ptcache_write(PTCacheID *pid, int cfra, int overwrite)
 
   if (pid->write_point) {
     for (i = 0; i < totpoint; i++) {
-      int write = pid->write_point(i, pid->calldata, pm->cur, cfra);
+      int write = pid->write_point(i, pid->calldata, cur, cfra);
       if (write) {
-        BKE_ptcache_mem_pointers_incr(pm);
+        BKE_ptcache_mem_pointers_incr(cur);
 
+        void *cur2[BPHYS_TOT_DATA];
         /* newly born particles have to be copied to previous cached frame */
-        if (overwrite && write == 2 && pm2 && BKE_ptcache_mem_pointers_seek(i, pm2)) {
-          pid->write_point(i, pid->calldata, pm2->cur, cfra);
+        if (overwrite && write == 2 && pm2 && BKE_ptcache_mem_pointers_seek(i, pm2, cur2)) {
+          pid->write_point(i, pid->calldata, cur2, cfra);
         }
       }
     }
@@ -3086,8 +3091,6 @@ static PointCache *ptcache_copy(PointCache *cache, const bool copy_data)
         }
       }
 
-      BKE_ptcache_mem_pointers_init(pm);
-
       BLI_addtail(&ncache->mem_cache, pmn);
     }
 
diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c
index e6d11398279..25efb210355 100644
--- a/source/blender/editors/physics/particle_edit.c
+++ b/source/blender/editors/physics/particle_edit.c
@@ -5200,7 +5200,8 @@ void PE_create_particle_edit(
 
       for (pm = cache->mem_cache.first; pm; pm = pm->next) {
         LOOP_POINTS {
-          if (BKE_ptcache_mem_pointers_seek(p, pm) == 0) {
+          void *cur[BPHYS_TOT_DATA];
+          if (BKE_ptcache_mem_pointers_seek(p, pm, cur) == 0) {
             continue;
           }
 
@@ -5212,12 +5213,12 @@ void PE_create_particle_edit(
             key = point->keys + point->totkey;
           }
 
-          key->co = pm->cur[BPHYS_DATA_LOCATION];
-          key->vel = pm->cur[BPHYS_DATA_VELOCITY];
-          key->rot = pm->cur[BPHYS_DATA_ROTATION];
+          key->co = cur[BPHYS_DATA_LOCATION];
+          key->vel = cur[BPHYS_DATA_VELOCITY];
+          key->rot = cur[BPHYS_DATA_ROTATION];
           key->ftime = (float)pm->frame;
           key->time = &key->ftime;
-          BKE_ptcache_mem_pointers_incr(pm);
+          BKE_ptcache_mem_pointers_incr(cur);
 
           point->totkey++;
         }
diff --git a/source/blender/editors/physics/particle_edit_undo.c b/source/blender/editors/physics/particle_edit_undo.c
index a4fcfa93a60..7523571733e 100644
--- a/source/blender/editors/physics/particle_edit_undo.c
+++ b/source/blender/editors/physics/particle_edit_undo.c
@@ -166,18 +166,19 @@ static void undoptcache_to_editcache(PTCacheUndo *undo, PTCacheEdit *edit)
       for (i = 0; i < BPHYS_TOT_DATA; i++) {
         pm->data[i] = MEM_dupallocN(pm->data[i]);
       }
-      BKE_ptcache_mem_pointers_init(pm);
+      void *cur[BPHYS_TOT_DATA];
+      BKE_ptcache_mem_pointers_init(pm, cur);
 
       LOOP_POINTS {
         LOOP_KEYS {
           if ((int)key->ftime == (int)pm->frame) {
-            key->co = pm->cur[BPHYS_DATA_LOCATION];
-            key->vel = pm->cur[BPHYS_DATA_VELOCITY];
-            key->rot = pm->cur[BPHYS_DATA_ROTATION];
+            key->co = cur[BPHYS_DATA_LOCATION];
+            key->vel = cur[BPHYS_DATA_VELOCITY];
+            key->rot = cur[BPHYS_DATA_ROTATION];
             key->time = &key->ftime;
           }
         }
-        BKE_ptcache_mem_pointers_incr(pm);
+        BKE_ptcache_mem_pointers_incr(cur);
       }
     }
   }
diff --git a/source/blender/makesdna/DNA_pointcache_types.h b/source/blender/makesdna/DNA_pointcache_types.h
index 79d46ffe112..de2fa3f10fe 100644
--- a/source/blender/makesdna/DNA_pointcache_types.h
+++ b/source/blender/makesdna/DNA_pointcache_types.h
@@ -64,8 +64,6 @@ typedef struct PTCacheMem {
 
   /** BPHYS_TOT_DATA. */
   void *data[8];
-  /** BPHYS_TOT_DATA. */
-  void *cur[8];
 
   struct ListBase extradata;
 } PTCacheMem;



More information about the Bf-blender-cvs mailing list