| 
									
										
										
										
											2022-02-11 09:07:11 +11:00
										 |  |  | /* SPDX-License-Identifier: Apache-2.0 */ | 
					
						
							| 
									
										
										
										
											2020-05-25 12:24:56 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "testing/testing.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "MEM_guardedalloc.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "BLI_task.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct TaskData { | 
					
						
							|  |  |  |   int value; | 
					
						
							|  |  |  |   int store; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void TaskData_increase_value(void *taskdata) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   TaskData *data = (TaskData *)taskdata; | 
					
						
							|  |  |  |   data->value += 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | static void TaskData_decrease_value(void *taskdata) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   TaskData *data = (TaskData *)taskdata; | 
					
						
							|  |  |  |   data->value -= 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | static void TaskData_multiply_by_two_value(void *taskdata) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   TaskData *data = (TaskData *)taskdata; | 
					
						
							|  |  |  |   data->value *= 2; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void TaskData_multiply_by_two_store(void *taskdata) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   TaskData *data = (TaskData *)taskdata; | 
					
						
							|  |  |  |   data->store *= 2; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void TaskData_store_value(void *taskdata) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   TaskData *data = (TaskData *)taskdata; | 
					
						
							|  |  |  |   data->store = data->value; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void TaskData_square_value(void *taskdata) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   TaskData *data = (TaskData *)taskdata; | 
					
						
							|  |  |  |   data->value *= data->value; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Sequential Test for using `BLI_task_graph` */ | 
					
						
							|  |  |  | TEST(task, GraphSequential) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   TaskData data = {0}; | 
					
						
							|  |  |  |   TaskGraph *graph = BLI_task_graph_create(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* 0 => 1 */ | 
					
						
							| 
									
										
										
										
											2020-11-06 17:49:09 +01:00
										 |  |  |   TaskNode *node_a = BLI_task_graph_node_create(graph, TaskData_increase_value, &data, nullptr); | 
					
						
							| 
									
										
										
										
											2020-05-25 12:24:56 +02:00
										 |  |  |   /* 1 => 2 */ | 
					
						
							|  |  |  |   TaskNode *node_b = BLI_task_graph_node_create( | 
					
						
							| 
									
										
										
										
											2020-11-06 17:49:09 +01:00
										 |  |  |       graph, TaskData_multiply_by_two_value, &data, nullptr); | 
					
						
							| 
									
										
										
										
											2020-05-25 12:24:56 +02:00
										 |  |  |   /* 2 => 1 */ | 
					
						
							| 
									
										
										
										
											2020-11-06 17:49:09 +01:00
										 |  |  |   TaskNode *node_c = BLI_task_graph_node_create(graph, TaskData_decrease_value, &data, nullptr); | 
					
						
							| 
									
										
										
										
											2020-05-25 12:24:56 +02:00
										 |  |  |   /* 2 => 1 */ | 
					
						
							| 
									
										
										
										
											2020-11-06 17:49:09 +01:00
										 |  |  |   TaskNode *node_d = BLI_task_graph_node_create(graph, TaskData_square_value, &data, nullptr); | 
					
						
							| 
									
										
										
										
											2020-05-25 12:24:56 +02:00
										 |  |  |   /* 1 => 1 */ | 
					
						
							| 
									
										
										
										
											2020-11-06 17:49:09 +01:00
										 |  |  |   TaskNode *node_e = BLI_task_graph_node_create(graph, TaskData_increase_value, &data, nullptr); | 
					
						
							| 
									
										
										
										
											2020-05-25 12:24:56 +02:00
										 |  |  |   /* 1 => 2 */ | 
					
						
							|  |  |  |   const int expected_value = 2; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   BLI_task_graph_edge_create(node_a, node_b); | 
					
						
							|  |  |  |   BLI_task_graph_edge_create(node_b, node_c); | 
					
						
							|  |  |  |   BLI_task_graph_edge_create(node_c, node_d); | 
					
						
							|  |  |  |   BLI_task_graph_edge_create(node_d, node_e); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   EXPECT_TRUE(BLI_task_graph_node_push_work(node_a)); | 
					
						
							|  |  |  |   BLI_task_graph_work_and_wait(graph); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   EXPECT_EQ(expected_value, data.value); | 
					
						
							|  |  |  |   BLI_task_graph_free(graph); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(task, GraphStartAtAnyNode) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   TaskData data = {4}; | 
					
						
							|  |  |  |   TaskGraph *graph = BLI_task_graph_create(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-06 17:49:09 +01:00
										 |  |  |   TaskNode *node_a = BLI_task_graph_node_create(graph, TaskData_increase_value, &data, nullptr); | 
					
						
							| 
									
										
										
										
											2020-05-25 12:24:56 +02:00
										 |  |  |   TaskNode *node_b = BLI_task_graph_node_create( | 
					
						
							| 
									
										
										
										
											2020-11-06 17:49:09 +01:00
										 |  |  |       graph, TaskData_multiply_by_two_value, &data, nullptr); | 
					
						
							|  |  |  |   TaskNode *node_c = BLI_task_graph_node_create(graph, TaskData_decrease_value, &data, nullptr); | 
					
						
							|  |  |  |   TaskNode *node_d = BLI_task_graph_node_create(graph, TaskData_square_value, &data, nullptr); | 
					
						
							|  |  |  |   TaskNode *node_e = BLI_task_graph_node_create(graph, TaskData_increase_value, &data, nullptr); | 
					
						
							| 
									
										
										
										
											2020-05-25 12:24:56 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // ((4 - 1) * (4 - 1)) + 1
 | 
					
						
							|  |  |  |   const int expected_value = 10; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   BLI_task_graph_edge_create(node_a, node_b); | 
					
						
							|  |  |  |   BLI_task_graph_edge_create(node_b, node_c); | 
					
						
							|  |  |  |   BLI_task_graph_edge_create(node_c, node_d); | 
					
						
							|  |  |  |   BLI_task_graph_edge_create(node_d, node_e); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   EXPECT_TRUE(BLI_task_graph_node_push_work(node_c)); | 
					
						
							|  |  |  |   BLI_task_graph_work_and_wait(graph); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   EXPECT_EQ(expected_value, data.value); | 
					
						
							|  |  |  |   BLI_task_graph_free(graph); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(task, GraphSplit) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   TaskData data = {1}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   TaskGraph *graph = BLI_task_graph_create(); | 
					
						
							| 
									
										
										
										
											2020-11-06 17:49:09 +01:00
										 |  |  |   TaskNode *node_a = BLI_task_graph_node_create(graph, TaskData_increase_value, &data, nullptr); | 
					
						
							|  |  |  |   TaskNode *node_b = BLI_task_graph_node_create(graph, TaskData_store_value, &data, nullptr); | 
					
						
							|  |  |  |   TaskNode *node_c = BLI_task_graph_node_create(graph, TaskData_increase_value, &data, nullptr); | 
					
						
							| 
									
										
										
										
											2020-05-25 12:24:56 +02:00
										 |  |  |   TaskNode *node_d = BLI_task_graph_node_create( | 
					
						
							| 
									
										
										
										
											2020-11-06 17:49:09 +01:00
										 |  |  |       graph, TaskData_multiply_by_two_store, &data, nullptr); | 
					
						
							| 
									
										
										
										
											2020-05-25 12:24:56 +02:00
										 |  |  |   BLI_task_graph_edge_create(node_a, node_b); | 
					
						
							|  |  |  |   BLI_task_graph_edge_create(node_b, node_c); | 
					
						
							|  |  |  |   BLI_task_graph_edge_create(node_b, node_d); | 
					
						
							|  |  |  |   EXPECT_TRUE(BLI_task_graph_node_push_work(node_a)); | 
					
						
							|  |  |  |   BLI_task_graph_work_and_wait(graph); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   EXPECT_EQ(3, data.value); | 
					
						
							|  |  |  |   EXPECT_EQ(4, data.store); | 
					
						
							|  |  |  |   BLI_task_graph_free(graph); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(task, GraphForest) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   TaskData data1 = {1}; | 
					
						
							|  |  |  |   TaskData data2 = {3}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   TaskGraph *graph = BLI_task_graph_create(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     TaskNode *tree1_node_a = BLI_task_graph_node_create( | 
					
						
							| 
									
										
										
										
											2020-11-06 17:49:09 +01:00
										 |  |  |         graph, TaskData_increase_value, &data1, nullptr); | 
					
						
							|  |  |  |     TaskNode *tree1_node_b = BLI_task_graph_node_create( | 
					
						
							|  |  |  |         graph, TaskData_store_value, &data1, nullptr); | 
					
						
							| 
									
										
										
										
											2020-05-25 12:24:56 +02:00
										 |  |  |     TaskNode *tree1_node_c = BLI_task_graph_node_create( | 
					
						
							| 
									
										
										
										
											2020-11-06 17:49:09 +01:00
										 |  |  |         graph, TaskData_increase_value, &data1, nullptr); | 
					
						
							| 
									
										
										
										
											2020-05-25 12:24:56 +02:00
										 |  |  |     TaskNode *tree1_node_d = BLI_task_graph_node_create( | 
					
						
							| 
									
										
										
										
											2020-11-06 17:49:09 +01:00
										 |  |  |         graph, TaskData_multiply_by_two_store, &data1, nullptr); | 
					
						
							| 
									
										
										
										
											2020-05-25 12:24:56 +02:00
										 |  |  |     BLI_task_graph_edge_create(tree1_node_a, tree1_node_b); | 
					
						
							|  |  |  |     BLI_task_graph_edge_create(tree1_node_b, tree1_node_c); | 
					
						
							|  |  |  |     BLI_task_graph_edge_create(tree1_node_b, tree1_node_d); | 
					
						
							|  |  |  |     EXPECT_TRUE(BLI_task_graph_node_push_work(tree1_node_a)); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     TaskNode *tree2_node_a = BLI_task_graph_node_create( | 
					
						
							| 
									
										
										
										
											2020-11-06 17:49:09 +01:00
										 |  |  |         graph, TaskData_increase_value, &data2, nullptr); | 
					
						
							|  |  |  |     TaskNode *tree2_node_b = BLI_task_graph_node_create( | 
					
						
							|  |  |  |         graph, TaskData_store_value, &data2, nullptr); | 
					
						
							| 
									
										
										
										
											2020-05-25 12:24:56 +02:00
										 |  |  |     TaskNode *tree2_node_c = BLI_task_graph_node_create( | 
					
						
							| 
									
										
										
										
											2020-11-06 17:49:09 +01:00
										 |  |  |         graph, TaskData_increase_value, &data2, nullptr); | 
					
						
							| 
									
										
										
										
											2020-05-25 12:24:56 +02:00
										 |  |  |     TaskNode *tree2_node_d = BLI_task_graph_node_create( | 
					
						
							| 
									
										
										
										
											2020-11-06 17:49:09 +01:00
										 |  |  |         graph, TaskData_multiply_by_two_store, &data2, nullptr); | 
					
						
							| 
									
										
										
										
											2020-05-25 12:24:56 +02:00
										 |  |  |     BLI_task_graph_edge_create(tree2_node_a, tree2_node_b); | 
					
						
							|  |  |  |     BLI_task_graph_edge_create(tree2_node_b, tree2_node_c); | 
					
						
							|  |  |  |     BLI_task_graph_edge_create(tree2_node_b, tree2_node_d); | 
					
						
							|  |  |  |     EXPECT_TRUE(BLI_task_graph_node_push_work(tree2_node_a)); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   BLI_task_graph_work_and_wait(graph); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   EXPECT_EQ(3, data1.value); | 
					
						
							|  |  |  |   EXPECT_EQ(4, data1.store); | 
					
						
							|  |  |  |   EXPECT_EQ(5, data2.value); | 
					
						
							|  |  |  |   EXPECT_EQ(8, data2.store); | 
					
						
							|  |  |  |   BLI_task_graph_free(graph); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(task, GraphTaskData) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   TaskData data = {0}; | 
					
						
							|  |  |  |   TaskGraph *graph = BLI_task_graph_create(); | 
					
						
							|  |  |  |   TaskNode *node_a = BLI_task_graph_node_create( | 
					
						
							|  |  |  |       graph, TaskData_store_value, &data, TaskData_increase_value); | 
					
						
							| 
									
										
										
										
											2020-11-06 17:49:09 +01:00
										 |  |  |   TaskNode *node_b = BLI_task_graph_node_create(graph, TaskData_store_value, &data, nullptr); | 
					
						
							| 
									
										
										
										
											2020-05-25 12:24:56 +02:00
										 |  |  |   BLI_task_graph_edge_create(node_a, node_b); | 
					
						
							|  |  |  |   EXPECT_TRUE(BLI_task_graph_node_push_work(node_a)); | 
					
						
							|  |  |  |   BLI_task_graph_work_and_wait(graph); | 
					
						
							|  |  |  |   EXPECT_EQ(0, data.value); | 
					
						
							|  |  |  |   EXPECT_EQ(0, data.store); | 
					
						
							|  |  |  |   BLI_task_graph_free(graph); | 
					
						
							|  |  |  |   /* data should be freed once */ | 
					
						
							|  |  |  |   EXPECT_EQ(1, data.value); | 
					
						
							|  |  |  |   EXPECT_EQ(0, data.store); | 
					
						
							|  |  |  | } |