diff options
author | Brecht Van Lommel <brecht@blender.org> | 2020-08-07 17:43:42 +0300 |
---|---|---|
committer | Brecht Van Lommel <brecht@blender.org> | 2020-08-10 19:14:00 +0300 |
commit | 53d203dea8230da4e80f3cc61468a4e24ff6759c (patch) | |
tree | 3f1b7498fb1a3108e60a4355bec0e4eef76110e4 /source/blender/blenlib/tests/BLI_linklist_lockfree_test.cc | |
parent | af77bf1f0f94cb07d5bf681d1f771d4106873780 (diff) |
Tests: move remaining gtests into their own module folders
And make them part of the blender_test runner. The one exception is blenlib
performance tests, which we don't want to run by default. They remain in their
own executable.
Differential Revision: https://developer.blender.org/D8498
Diffstat (limited to 'source/blender/blenlib/tests/BLI_linklist_lockfree_test.cc')
-rw-r--r-- | source/blender/blenlib/tests/BLI_linklist_lockfree_test.cc | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/source/blender/blenlib/tests/BLI_linklist_lockfree_test.cc b/source/blender/blenlib/tests/BLI_linklist_lockfree_test.cc new file mode 100644 index 00000000000..d1a527d57ac --- /dev/null +++ b/source/blender/blenlib/tests/BLI_linklist_lockfree_test.cc @@ -0,0 +1,111 @@ +/* Apache License, Version 2.0 */ + +#include "testing/testing.h" + +#include "MEM_guardedalloc.h" + +#include "BLI_linklist_lockfree.h" +#include "BLI_task.h" +#include "BLI_threads.h" +#include "BLI_utildefines.h" + +TEST(LockfreeLinkList, Init) +{ + LockfreeLinkList list; + BLI_linklist_lockfree_init(&list); + EXPECT_EQ(list.head, &list.dummy_node); + EXPECT_EQ(list.tail, &list.dummy_node); + BLI_linklist_lockfree_free(&list, NULL); +} + +TEST(LockfreeLinkList, InsertSingle) +{ + LockfreeLinkList list; + LockfreeLinkNode node; + BLI_linklist_lockfree_init(&list); + BLI_linklist_lockfree_insert(&list, &node); + EXPECT_EQ(list.head, &list.dummy_node); + EXPECT_EQ(list.head->next, &node); + EXPECT_EQ(list.tail, &node); + BLI_linklist_lockfree_free(&list, NULL); +} + +TEST(LockfreeLinkList, InsertMultiple) +{ + static const int num_nodes = 128; + LockfreeLinkList list; + LockfreeLinkNode nodes[num_nodes]; + BLI_linklist_lockfree_init(&list); + /* Insert all the nodes. */ + for (int i = 0; i < num_nodes; ++i) { + BLI_linklist_lockfree_insert(&list, &nodes[i]); + } + /* Check head and tail. */ + EXPECT_EQ(list.head, &list.dummy_node); + EXPECT_EQ(list.tail, &nodes[num_nodes - 1]); + /* Check rest of the nodes. */ + int node_index = 0; + for (LockfreeLinkNode *node = BLI_linklist_lockfree_begin(&list); node != NULL; + node = node->next, ++node_index) { + EXPECT_EQ(node, &nodes[node_index]); + if (node_index != num_nodes - 1) { + EXPECT_EQ(node->next, &nodes[node_index + 1]); + } + } + /* Free list. */ + BLI_linklist_lockfree_free(&list, NULL); +} + +namespace { + +struct IndexedNode { + IndexedNode *next; + int index; +}; + +void concurrent_insert(TaskPool *__restrict pool, void *taskdata) +{ + LockfreeLinkList *list = (LockfreeLinkList *)BLI_task_pool_user_data(pool); + CHECK_NOTNULL(list); + IndexedNode *node = (IndexedNode *)MEM_mallocN(sizeof(IndexedNode), "test node"); + node->index = POINTER_AS_INT(taskdata); + BLI_linklist_lockfree_insert(list, (LockfreeLinkNode *)node); +} + +} // namespace + +TEST(LockfreeLinkList, InsertMultipleConcurrent) +{ + static const int num_nodes = 655360; + /* Initialize list. */ + LockfreeLinkList list; + BLI_linklist_lockfree_init(&list); + /* Initialize task scheduler and pool. */ + TaskPool *pool = BLI_task_pool_create_suspended(&list, TASK_PRIORITY_HIGH); + /* Push tasks to the pool. */ + for (int i = 0; i < num_nodes; ++i) { + BLI_task_pool_push(pool, concurrent_insert, POINTER_FROM_INT(i), false, NULL); + } + /* Run all the tasks. */ + BLI_task_pool_work_and_wait(pool); + /* Verify we've got all the data properly inserted. */ + EXPECT_EQ(list.head, &list.dummy_node); + bool *visited_nodes = (bool *)MEM_callocN(sizeof(bool) * num_nodes, "visited nodes"); + /* First, we make sure that none of the nodes are added twice. */ + for (LockfreeLinkNode *node_v = BLI_linklist_lockfree_begin(&list); node_v != NULL; + node_v = node_v->next) { + IndexedNode *node = (IndexedNode *)node_v; + EXPECT_GE(node->index, 0); + EXPECT_LT(node->index, num_nodes); + EXPECT_FALSE(visited_nodes[node->index]); + visited_nodes[node->index] = true; + } + /* Then we make sure node was added. */ + for (int node_index = 0; node_index < num_nodes; ++node_index) { + EXPECT_TRUE(visited_nodes[node_index]); + } + MEM_freeN(visited_nodes); + /* Cleanup data. */ + BLI_linklist_lockfree_free(&list, MEM_freeN); + BLI_task_pool_free(pool); +} |