Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2021-06-09 15:49:45 +0300
committerCampbell Barton <ideasman42@gmail.com>2021-06-09 17:55:04 +0300
commit14f3b2cdad2d7b00ce3ea27bf8eb0087ac2a6cbd (patch)
tree889d20ad5cf627057bb619e18ec47d39cabafc99 /source/blender/blenlib/tests
parentf546b0800b9121b24b1292f1ec602ed9964d1848 (diff)
BLI_task: add TLS support to BLI_task_parallel_mempool
Support thread local storage for BLI_task_parallel_mempool, as well as support for the reduce and free callbacks. mempool_iter_threadsafe_* functions have been moved into a private header thats only shared between task_iterator.c and BLI_mempool.c so the TLS can be made part of the iterator array without having to rely on passing in struct offsets. Add test task.MempoolIterTLS that ensures reduce and free are working as expected. Reviewed By: mont29 Ref D11548
Diffstat (limited to 'source/blender/blenlib/tests')
-rw-r--r--source/blender/blenlib/tests/BLI_task_test.cc102
1 files changed, 100 insertions, 2 deletions
diff --git a/source/blender/blenlib/tests/BLI_task_test.cc b/source/blender/blenlib/tests/BLI_task_test.cc
index fce3e56d105..75d89656a0f 100644
--- a/source/blender/blenlib/tests/BLI_task_test.cc
+++ b/source/blender/blenlib/tests/BLI_task_test.cc
@@ -67,7 +67,9 @@ TEST(task, RangeIter)
/* *** Parallel iterations over mempool items. *** */
-static void task_mempool_iter_func(void *userdata, MempoolIterData *item)
+static void task_mempool_iter_func(void *userdata,
+ MempoolIterData *item,
+ const TaskParallelTLS *__restrict UNUSED(tls))
{
int *data = (int *)item;
int *count = (int *)userdata;
@@ -119,7 +121,10 @@ TEST(task, MempoolIter)
}
}
- BLI_task_parallel_mempool(mempool, &num_items, task_mempool_iter_func, true);
+ TaskParallelSettings settings;
+ BLI_parallel_mempool_settings_defaults(&settings);
+
+ BLI_task_parallel_mempool(mempool, &num_items, task_mempool_iter_func, &settings);
/* Those checks should ensure us all items of the mempool were processed once, and only once - as
* expected. */
@@ -134,6 +139,99 @@ TEST(task, MempoolIter)
BLI_threadapi_exit();
}
+/* *** Parallel iterations over mempool items with TLS. *** */
+
+typedef struct TaskMemPool_Chunk {
+ ListBase *accumulate_items;
+} TaskMemPool_Chunk;
+
+static void task_mempool_iter_tls_func(void *UNUSED(userdata),
+ MempoolIterData *item,
+ const TaskParallelTLS *__restrict tls)
+{
+ TaskMemPool_Chunk *task_data = (TaskMemPool_Chunk *)tls->userdata_chunk;
+ int *data = (int *)item;
+
+ EXPECT_TRUE(data != nullptr);
+ if (task_data->accumulate_items == nullptr) {
+ task_data->accumulate_items = (ListBase *)MEM_callocN(sizeof(ListBase), __func__);
+ }
+
+ /* Flip to prove this has been touched. */
+ *data = -*data;
+
+ BLI_addtail(task_data->accumulate_items, BLI_genericNodeN(data));
+}
+
+static void task_mempool_iter_tls_reduce(const void *__restrict UNUSED(userdata),
+ void *__restrict chunk_join,
+ void *__restrict chunk)
+{
+ TaskMemPool_Chunk *join_chunk = (TaskMemPool_Chunk *)chunk_join;
+ TaskMemPool_Chunk *data_chunk = (TaskMemPool_Chunk *)chunk;
+
+ if (data_chunk->accumulate_items != nullptr) {
+ if (join_chunk->accumulate_items == nullptr) {
+ join_chunk->accumulate_items = (ListBase *)MEM_callocN(sizeof(ListBase), __func__);
+ }
+ BLI_movelisttolist(join_chunk->accumulate_items, data_chunk->accumulate_items);
+ }
+}
+
+static void task_mempool_iter_tls_free(const void *UNUSED(userdata),
+ void *__restrict userdata_chunk)
+{
+ TaskMemPool_Chunk *task_data = (TaskMemPool_Chunk *)userdata_chunk;
+ MEM_freeN(task_data->accumulate_items);
+}
+
+TEST(task, MempoolIterTLS)
+{
+ int *data[NUM_ITEMS];
+ BLI_threadapi_init();
+ BLI_mempool *mempool = BLI_mempool_create(
+ sizeof(*data[0]), NUM_ITEMS, 32, BLI_MEMPOOL_ALLOW_ITER);
+
+ int i;
+
+ /* Add numbers negative `1..NUM_ITEMS` inclusive. */
+ int num_items = 0;
+ for (i = 0; i < NUM_ITEMS; i++) {
+ data[i] = (int *)BLI_mempool_alloc(mempool);
+ *data[i] = -(i + 1);
+ num_items++;
+ }
+
+ TaskParallelSettings settings;
+ BLI_parallel_mempool_settings_defaults(&settings);
+
+ TaskMemPool_Chunk tls_data;
+
+ settings.userdata_chunk = &tls_data;
+ settings.userdata_chunk_size = sizeof(tls_data);
+
+ settings.func_free = task_mempool_iter_tls_free;
+ settings.func_reduce = task_mempool_iter_tls_reduce;
+
+ BLI_task_parallel_mempool(mempool, nullptr, task_mempool_iter_tls_func, &settings);
+
+ EXPECT_EQ(BLI_listbase_count(tls_data.accumulate_items), NUM_ITEMS);
+
+ /* Check that all elements are added into the list once. */
+ int num_accum = 0;
+ for (LinkData *link = (LinkData *)tls_data.accumulate_items->first; link; link = link->next) {
+ int *data = (int *)link->data;
+ num_accum += *data;
+ }
+ EXPECT_EQ(num_accum, (NUM_ITEMS * (NUM_ITEMS + 1)) / 2);
+
+ BLI_freelistN(tls_data.accumulate_items);
+ MEM_freeN(tls_data.accumulate_items);
+
+ BLI_mempool_destroy(mempool);
+ BLI_threadapi_exit();
+}
+
/* *** Parallel iterations over double-linked list items. *** */
static void task_listbase_iter_func(void *userdata,