Blender V4.3
BLI_task_graph_test.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#include "testing/testing.h"
6
7#include "MEM_guardedalloc.h"
8
9#include "BLI_task.h"
10
11struct TaskData {
12 int value;
13 int store;
14};
15
16static void TaskData_increase_value(void *taskdata)
17{
18 TaskData *data = (TaskData *)taskdata;
19 data->value += 1;
20}
21static void TaskData_decrease_value(void *taskdata)
22{
23 TaskData *data = (TaskData *)taskdata;
24 data->value -= 1;
25}
26static void TaskData_multiply_by_two_value(void *taskdata)
27{
28 TaskData *data = (TaskData *)taskdata;
29 data->value *= 2;
30}
31
32static void TaskData_multiply_by_two_store(void *taskdata)
33{
34 TaskData *data = (TaskData *)taskdata;
35 data->store *= 2;
36}
37
38static void TaskData_store_value(void *taskdata)
39{
40 TaskData *data = (TaskData *)taskdata;
41 data->store = data->value;
42}
43
44static void TaskData_square_value(void *taskdata)
45{
46 TaskData *data = (TaskData *)taskdata;
47 data->value *= data->value;
48}
49
50/* Sequential Test for using `BLI_task_graph` */
51TEST(task, GraphSequential)
52{
53 TaskData data = {0};
55
56 /* 0 => 1 */
57 TaskNode *node_a = BLI_task_graph_node_create(graph, TaskData_increase_value, &data, nullptr);
58 /* 1 => 2 */
60 graph, TaskData_multiply_by_two_value, &data, nullptr);
61 /* 2 => 1 */
62 TaskNode *node_c = BLI_task_graph_node_create(graph, TaskData_decrease_value, &data, nullptr);
63 /* 2 => 1 */
64 TaskNode *node_d = BLI_task_graph_node_create(graph, TaskData_square_value, &data, nullptr);
65 /* 1 => 1 */
66 TaskNode *node_e = BLI_task_graph_node_create(graph, TaskData_increase_value, &data, nullptr);
67 /* 1 => 2 */
68 const int expected_value = 2;
69
70 BLI_task_graph_edge_create(node_a, node_b);
71 BLI_task_graph_edge_create(node_b, node_c);
72 BLI_task_graph_edge_create(node_c, node_d);
73 BLI_task_graph_edge_create(node_d, node_e);
74
75 EXPECT_TRUE(BLI_task_graph_node_push_work(node_a));
77
78 EXPECT_EQ(expected_value, data.value);
80}
81
82TEST(task, GraphStartAtAnyNode)
83{
84 TaskData data = {4};
86
87 TaskNode *node_a = BLI_task_graph_node_create(graph, TaskData_increase_value, &data, nullptr);
89 graph, TaskData_multiply_by_two_value, &data, nullptr);
90 TaskNode *node_c = BLI_task_graph_node_create(graph, TaskData_decrease_value, &data, nullptr);
91 TaskNode *node_d = BLI_task_graph_node_create(graph, TaskData_square_value, &data, nullptr);
92 TaskNode *node_e = BLI_task_graph_node_create(graph, TaskData_increase_value, &data, nullptr);
93
94 // ((4 - 1) * (4 - 1)) + 1
95 const int expected_value = 10;
96
97 BLI_task_graph_edge_create(node_a, node_b);
98 BLI_task_graph_edge_create(node_b, node_c);
99 BLI_task_graph_edge_create(node_c, node_d);
100 BLI_task_graph_edge_create(node_d, node_e);
101
102 EXPECT_TRUE(BLI_task_graph_node_push_work(node_c));
104
105 EXPECT_EQ(expected_value, data.value);
106 BLI_task_graph_free(graph);
107}
108
109TEST(task, GraphSplit)
110{
111 TaskData data = {1};
112
114 TaskNode *node_a = BLI_task_graph_node_create(graph, TaskData_increase_value, &data, nullptr);
115 TaskNode *node_b = BLI_task_graph_node_create(graph, TaskData_store_value, &data, nullptr);
116 TaskNode *node_c = BLI_task_graph_node_create(graph, TaskData_increase_value, &data, nullptr);
118 graph, TaskData_multiply_by_two_store, &data, nullptr);
119 BLI_task_graph_edge_create(node_a, node_b);
120 BLI_task_graph_edge_create(node_b, node_c);
121 BLI_task_graph_edge_create(node_b, node_d);
122 EXPECT_TRUE(BLI_task_graph_node_push_work(node_a));
124
125 EXPECT_EQ(3, data.value);
126 EXPECT_EQ(4, data.store);
127 BLI_task_graph_free(graph);
128}
129
130TEST(task, GraphForest)
131{
132 TaskData data1 = {1};
133 TaskData data2 = {3};
134
136
137 {
138 TaskNode *tree1_node_a = BLI_task_graph_node_create(
139 graph, TaskData_increase_value, &data1, nullptr);
140 TaskNode *tree1_node_b = BLI_task_graph_node_create(
141 graph, TaskData_store_value, &data1, nullptr);
142 TaskNode *tree1_node_c = BLI_task_graph_node_create(
143 graph, TaskData_increase_value, &data1, nullptr);
144 TaskNode *tree1_node_d = BLI_task_graph_node_create(
145 graph, TaskData_multiply_by_two_store, &data1, nullptr);
146 BLI_task_graph_edge_create(tree1_node_a, tree1_node_b);
147 BLI_task_graph_edge_create(tree1_node_b, tree1_node_c);
148 BLI_task_graph_edge_create(tree1_node_b, tree1_node_d);
149 EXPECT_TRUE(BLI_task_graph_node_push_work(tree1_node_a));
150 }
151
152 {
153 TaskNode *tree2_node_a = BLI_task_graph_node_create(
154 graph, TaskData_increase_value, &data2, nullptr);
155 TaskNode *tree2_node_b = BLI_task_graph_node_create(
156 graph, TaskData_store_value, &data2, nullptr);
157 TaskNode *tree2_node_c = BLI_task_graph_node_create(
158 graph, TaskData_increase_value, &data2, nullptr);
159 TaskNode *tree2_node_d = BLI_task_graph_node_create(
160 graph, TaskData_multiply_by_two_store, &data2, nullptr);
161 BLI_task_graph_edge_create(tree2_node_a, tree2_node_b);
162 BLI_task_graph_edge_create(tree2_node_b, tree2_node_c);
163 BLI_task_graph_edge_create(tree2_node_b, tree2_node_d);
164 EXPECT_TRUE(BLI_task_graph_node_push_work(tree2_node_a));
165 }
166
168
169 EXPECT_EQ(3, data1.value);
170 EXPECT_EQ(4, data1.store);
171 EXPECT_EQ(5, data2.value);
172 EXPECT_EQ(8, data2.store);
173 BLI_task_graph_free(graph);
174}
175
176TEST(task, GraphTaskData)
177{
178 TaskData data = {0};
182 TaskNode *node_b = BLI_task_graph_node_create(graph, TaskData_store_value, &data, nullptr);
183 BLI_task_graph_edge_create(node_a, node_b);
184 EXPECT_TRUE(BLI_task_graph_node_push_work(node_a));
186 EXPECT_EQ(0, data.value);
187 EXPECT_EQ(0, data.store);
188 BLI_task_graph_free(graph);
189 /* data should be freed once */
190 EXPECT_EQ(1, data.value);
191 EXPECT_EQ(0, data.store);
192}
EXPECT_EQ(BLI_expr_pylike_eval(expr, nullptr, 0, &result), EXPR_PYLIKE_INVALID)
struct TaskNode * BLI_task_graph_node_create(struct TaskGraph *task_graph, TaskGraphNodeRunFunction run, void *user_data, TaskGraphNodeFreeFunction free_func)
void BLI_task_graph_edge_create(struct TaskNode *from_node, struct TaskNode *to_node)
bool BLI_task_graph_node_push_work(struct TaskNode *task_node)
void BLI_task_graph_free(struct TaskGraph *task_graph)
struct TaskGraph * BLI_task_graph_create(void)
void BLI_task_graph_work_and_wait(struct TaskGraph *task_graph)
TEST(task, GraphSequential)
static void TaskData_decrease_value(void *taskdata)
static void TaskData_square_value(void *taskdata)
static void TaskData_increase_value(void *taskdata)
static void TaskData_multiply_by_two_value(void *taskdata)
static void TaskData_store_value(void *taskdata)
static void TaskData_multiply_by_two_store(void *taskdata)
Read Guarded memory(de)allocation.