Changeset View
Changeset View
Standalone View
Standalone View
tests/gtests/blenlib/BLI_linklist_lockfree_test.cc
| Show First 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | |||||
| namespace { | namespace { | ||||
| struct IndexedNode { | struct IndexedNode { | ||||
| IndexedNode *next; | IndexedNode *next; | ||||
| int index; | int index; | ||||
| }; | }; | ||||
| void concurrent_insert(TaskPool *__restrict pool, void *taskdata, int /*threadid*/) | void concurrent_insert(TaskPool *__restrict pool, void *taskdata) | ||||
| { | { | ||||
| LockfreeLinkList *list = (LockfreeLinkList *)BLI_task_pool_userdata(pool); | LockfreeLinkList *list = (LockfreeLinkList *)BLI_task_pool_tbb_user_data(pool); | ||||
| CHECK_NOTNULL(list); | CHECK_NOTNULL(list); | ||||
| IndexedNode *node = (IndexedNode *)MEM_mallocN(sizeof(IndexedNode), "test node"); | IndexedNode *node = (IndexedNode *)MEM_mallocN(sizeof(IndexedNode), "test node"); | ||||
| node->index = POINTER_AS_INT(taskdata); | node->index = POINTER_AS_INT(taskdata); | ||||
| BLI_linklist_lockfree_insert(list, (LockfreeLinkNode *)node); | BLI_linklist_lockfree_insert(list, (LockfreeLinkNode *)node); | ||||
| } | } | ||||
| } // namespace | } // namespace | ||||
| TEST(LockfreeLinkList, InsertMultipleConcurrent) | TEST(LockfreeLinkList, InsertMultipleConcurrent) | ||||
| { | { | ||||
| static const int num_threads = 512; | static const int num_threads = 512; | ||||
| static const int num_nodes = 655360; | static const int num_nodes = 655360; | ||||
| /* Initialize list. */ | /* Initialize list. */ | ||||
| LockfreeLinkList list; | LockfreeLinkList list; | ||||
| BLI_linklist_lockfree_init(&list); | BLI_linklist_lockfree_init(&list); | ||||
| /* Initialize task scheduler and pool. */ | /* Initialize task scheduler and pool. */ | ||||
| TaskScheduler *scheduler = BLI_task_scheduler_create(num_threads); | TaskScheduler *scheduler = BLI_task_scheduler_legacy_create(num_threads); | ||||
| TaskPool *pool = BLI_task_pool_create_suspended(scheduler, &list, TASK_PRIORITY_HIGH); | TaskPool *pool = BLI_task_pool_tbb_create_suspended(scheduler, &list, TASK_PRIORITY_HIGH); | ||||
| /* Push tasks to the pool. */ | /* Push tasks to the pool. */ | ||||
| for (int i = 0; i < num_nodes; ++i) { | for (int i = 0; i < num_nodes; ++i) { | ||||
| BLI_task_pool_push(pool, concurrent_insert, POINTER_FROM_INT(i), false, NULL); | BLI_task_pool_tbb_push(pool, concurrent_insert, POINTER_FROM_INT(i), false, NULL); | ||||
| } | } | ||||
| /* Run all the tasks. */ | /* Run all the tasks. */ | ||||
| BLI_threaded_malloc_begin(); | BLI_threaded_malloc_begin(); | ||||
| BLI_task_pool_work_and_wait(pool); | BLI_task_pool_tbb_work_and_wait(pool); | ||||
| BLI_threaded_malloc_end(); | BLI_threaded_malloc_end(); | ||||
| /* Verify we've got all the data properly inserted. */ | /* Verify we've got all the data properly inserted. */ | ||||
| EXPECT_EQ(list.head, &list.dummy_node); | EXPECT_EQ(list.head, &list.dummy_node); | ||||
| bool *visited_nodes = (bool *)MEM_callocN(sizeof(bool) * num_nodes, "visited nodes"); | bool *visited_nodes = (bool *)MEM_callocN(sizeof(bool) * num_nodes, "visited nodes"); | ||||
| /* First, we make sure that none of the nodes are added twice. */ | /* First, we make sure that none of the nodes are added twice. */ | ||||
| for (LockfreeLinkNode *node_v = BLI_linklist_lockfree_begin(&list); node_v != NULL; | for (LockfreeLinkNode *node_v = BLI_linklist_lockfree_begin(&list); node_v != NULL; | ||||
| node_v = node_v->next) { | node_v = node_v->next) { | ||||
| IndexedNode *node = (IndexedNode *)node_v; | IndexedNode *node = (IndexedNode *)node_v; | ||||
| EXPECT_GE(node->index, 0); | EXPECT_GE(node->index, 0); | ||||
| EXPECT_LT(node->index, num_nodes); | EXPECT_LT(node->index, num_nodes); | ||||
| EXPECT_FALSE(visited_nodes[node->index]); | EXPECT_FALSE(visited_nodes[node->index]); | ||||
| visited_nodes[node->index] = true; | visited_nodes[node->index] = true; | ||||
| } | } | ||||
| /* Then we make sure node was added. */ | /* Then we make sure node was added. */ | ||||
| for (int node_index = 0; node_index < num_nodes; ++node_index) { | for (int node_index = 0; node_index < num_nodes; ++node_index) { | ||||
| EXPECT_TRUE(visited_nodes[node_index]); | EXPECT_TRUE(visited_nodes[node_index]); | ||||
| } | } | ||||
| MEM_freeN(visited_nodes); | MEM_freeN(visited_nodes); | ||||
| /* Cleanup data. */ | /* Cleanup data. */ | ||||
| BLI_linklist_lockfree_free(&list, MEM_freeN); | BLI_linklist_lockfree_free(&list, MEM_freeN); | ||||
| BLI_task_pool_free(pool); | BLI_task_pool_tbb_free(pool); | ||||
| BLI_task_scheduler_free(scheduler); | BLI_task_scheduler_legacy_free(scheduler); | ||||
| } | } | ||||