From 1775c39986594244630e7f42931d1208fe020d02 Mon Sep 17 00:00:00 2001 From: Germano Cavalcante Date: Thu, 29 Jul 2021 10:35:12 -0300 Subject: Fix 'BLI_task_parallel_mempool' keeping 'user_chunk' unchanged When `BLI_task_parallel_mempool` does not use threading, the `userdata_chunk` is allocated locally simulating a TLS. However `func_reduce` is not called so the original chunk is ignored. `task_parallel_iterator_no_threads` is another function that doesn't call `func_reduce`. It also ignores `userdata_chunk_local` in the main iterator. The solution in these cases is not to create a `userdata_chunk_local`. This fixes T90131 Differential Revision: https://developer.blender.org/D12067 --- source/blender/blenlib/intern/task_iterator.c | 31 +++++++++++---------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/source/blender/blenlib/intern/task_iterator.c b/source/blender/blenlib/intern/task_iterator.c index 06087869685..6378d88e2b1 100644 --- a/source/blender/blenlib/intern/task_iterator.c +++ b/source/blender/blenlib/intern/task_iterator.c @@ -180,14 +180,9 @@ static void task_parallel_iterator_no_threads(const TaskParallelSettings *settin { /* Prepare user's TLS data. */ void *userdata_chunk = settings->userdata_chunk; - const size_t userdata_chunk_size = settings->userdata_chunk_size; - void *userdata_chunk_local = NULL; - const bool use_userdata_chunk = (userdata_chunk_size != 0) && (userdata_chunk != NULL); - if (use_userdata_chunk) { - userdata_chunk_local = MALLOCA(userdata_chunk_size); - memcpy(userdata_chunk_local, userdata_chunk, userdata_chunk_size); + if (userdata_chunk) { if (settings->func_init != NULL) { - settings->func_init(state->userdata, userdata_chunk_local); + settings->func_init(state->userdata, userdata_chunk); } } @@ -196,12 +191,11 @@ static void task_parallel_iterator_no_threads(const TaskParallelSettings *settin parallel_iterator_func_do(state, userdata_chunk); - if (use_userdata_chunk) { + if (userdata_chunk) { if (settings->func_free != NULL) { /* `func_free` should only free data that was created during execution of `func`. */ - settings->func_free(state->userdata, userdata_chunk_local); + settings->func_free(state->userdata, userdata_chunk); } - MALLOCA_FREE(userdata_chunk_local, userdata_chunk_size); } } @@ -415,19 +409,16 @@ void BLI_task_parallel_mempool(BLI_mempool *mempool, void *userdata_chunk = settings->userdata_chunk; const size_t userdata_chunk_size = settings->userdata_chunk_size; - void *userdata_chunk_local = NULL; void *userdata_chunk_array = NULL; const bool use_userdata_chunk = (userdata_chunk_size != 0) && (userdata_chunk != NULL); if (!settings->use_threading) { TaskParallelTLS tls = {NULL}; if (use_userdata_chunk) { - userdata_chunk_local = MALLOCA(userdata_chunk_size); - memcpy(userdata_chunk_local, userdata_chunk, userdata_chunk_size); if (settings->func_init != NULL) { - settings->func_init(userdata, userdata_chunk_local); + settings->func_init(userdata, userdata_chunk); } - tls.userdata_chunk = userdata_chunk_local; + tls.userdata_chunk = userdata_chunk; } BLI_mempool_iter iter; @@ -438,12 +429,13 @@ void BLI_task_parallel_mempool(BLI_mempool *mempool, func(userdata, item, &tls); } - if (settings->func_free != NULL) { - /* `func_free` should only free data that was created during execution of `func`. */ - settings->func_free(userdata, userdata_chunk_local); + if (use_userdata_chunk) { + if (settings->func_free != NULL) { + /* `func_free` should only free data that was created during execution of `func`. */ + settings->func_free(userdata, userdata_chunk); + } } - MALLOCA_FREE(userdata_chunk_local, userdata_chunk_size); return; } @@ -468,6 +460,7 @@ void BLI_task_parallel_mempool(BLI_mempool *mempool, mempool, (size_t)num_tasks); for (int i = 0; i < num_tasks; i++) { + void *userdata_chunk_local = NULL; if (use_userdata_chunk) { userdata_chunk_local = (char *)userdata_chunk_array + (userdata_chunk_size * i); memcpy(userdata_chunk_local, userdata_chunk, userdata_chunk_size); -- cgit v1.2.3