3 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 * Licensed under the Apache License, Version 2.0 (the License);
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
20 #include "utility/sync_util.h"
21 #include "engine-controller/task_spec.h"
22 #include "engine-controller/task_spec_internal.h"
23 #include "engine-controller/param_spec_internal.h"
26 #define EXPORT_API __attribute__ ((visibility("default")))
29 #ifndef SYNC_AGENT_LOG
31 #define LOG_TAG "AF_EC"
34 static sync_agent_ec_task_spec_s *_task_spec_new_default_task_spec(sync_agent_ec_char * task_name, sync_agent_ec_pointer post_task_func_usr_data, sync_agent_post_task_cb post_task_callback, sync_agent_ec_uint param_cnt,
35 sync_agent_ec_param_spec_s ** param_spec_array);
36 static void _task_spec_free_task_spec(sync_agent_ec_task_spec_s * task_spec);
38 static ec_child_tasks_info_t *_task_spec_new_child_tasks_info(sync_agent_ec_uint parent_param_cnt, sync_agent_ec_uint child_task_cnt, sync_agent_ec_task_spec_s ** child_task_array);
40 static void __task_spec_free_child_tasks_info(ec_child_tasks_info_t * child_task_info);
42 static ec_dynamic_container_task_specific_t *_task_spec_new_dynamic_container_task_specific(sync_agent_ec_uint parent_param_cnt, sync_agent_calculate_case_cb calculate_case_func, sync_agent_ec_uint case_cnt, sync_agent_ec_int * case_array,
43 sync_agent_ec_uint * child_task_cnt_array, sync_agent_ec_task_spec_s *** child_task_array_per_case_array);
45 static void __task_spec_free_dynamic_container_task_specific(ec_dynamic_container_task_specific_t * pDynamic_container_task_specific);
47 static sync_agent_ec_param_spec_s *__task_spec_find_param_spec(sync_agent_ec_task_spec_s * task_spec, sync_agent_ec_int param_index);
49 static sync_agent_ec_error_e __task_spec_validate_container_task_spec(sync_agent_ec_task_spec_s * container_task_spec);
51 static sync_agent_ec_error_e _task_spec_validate_dynamic_container_task_spec(sync_agent_ec_task_spec_s * dynamic_container_task_spec);
53 static sync_agent_ec_error_e __task_spec_validate_param_index(sync_agent_ec_task_spec_s * task_spec, sync_agent_ec_int param_index);
55 static sync_agent_ec_error_e _task_spec_validate_set_control_flow_input_parameters(sync_agent_ec_task_spec_s * container_task_spec, sync_agent_ec_int from_task_index, sync_agent_ec_int to_task_index);
57 static sync_agent_ec_error_e _task_spec_validate_set_control_flow_input_parameters_on_dynamic_case(sync_agent_ec_int dynamic_case, sync_agent_ec_task_spec_s * dynamic_container_task_spec, sync_agent_ec_int from_task_index, sync_agent_ec_int to_task_index);
59 static sync_agent_ec_error_e _task_spec_validate_set_data_flow_input_parameters(sync_agent_ec_task_spec_s * container_task_spec, sync_agent_ec_int from_task_index, sync_agent_ec_int from_param_index, sync_agent_ec_int to_task_index,
60 sync_agent_ec_int to_param_index);
62 static sync_agent_ec_error_e _task_spec_validate_set_data_flow_input_parameters_on_dynamic_case(sync_agent_ec_int dynamic_case, sync_agent_ec_task_spec_s * container_task_spec, sync_agent_ec_int from_task_index, sync_agent_ec_int from_param_index,
63 sync_agent_ec_int to_task_index, sync_agent_ec_int to_param_index);
65 ec_data_flow_edges_t *ec_data_flow_edges_new(sync_agent_ec_int parent_task_param_cnt, sync_agent_ec_uint child_task_cnt, sync_agent_ec_task_spec_s ** child_task_array)
69 sync_agent_ec_int i = 0;
70 sync_agent_ec_int total_param_cnt = 0;
72 ec_data_flow_edges_t *data_flow_edges = (ec_data_flow_edges_t *) calloc(1, sizeof(ec_data_flow_edges_t));
73 if (data_flow_edges == NULL) {
77 data_flow_edges->child_task_param_start_index_array = (sync_agent_ec_int *) calloc(child_task_cnt, sizeof(sync_agent_ec_int));
78 if (data_flow_edges->child_task_param_start_index_array == NULL) {
82 /* compute total param cnt and child_task_param_start_index_array */
83 total_param_cnt = parent_task_param_cnt;
84 for (i = 0; i < child_task_cnt; i++) {
85 data_flow_edges->child_task_param_start_index_array[i] = total_param_cnt;
86 total_param_cnt += child_task_array[i]->task_param_cnt;
89 data_flow_edges->child_task_cnt = child_task_cnt;
90 data_flow_edges->total_param_cnt = total_param_cnt;
92 sync_agent_ec_int *from_param_array = (sync_agent_ec_int *) malloc(total_param_cnt * sizeof(sync_agent_ec_int));
93 if (from_param_array == NULL) {
97 data_flow_edges->from_param_array = from_param_array;
98 for (i = 0; i < total_param_cnt; i++) {
99 from_param_array[i] = -1; /* when -1, no from_param exist */
104 return data_flow_edges;
107 ec_data_flow_edges_free(data_flow_edges);
111 void ec_data_flow_edges_free(ec_data_flow_edges_t * data_flow_edges)
115 if (data_flow_edges != NULL) {
116 if (data_flow_edges->child_task_param_start_index_array != NULL) {
117 free(data_flow_edges->child_task_param_start_index_array);
120 if (data_flow_edges->from_param_array != NULL) {
121 free(data_flow_edges->from_param_array);
124 free(data_flow_edges);
130 sync_agent_ec_int ec_data_flow_edges_compute_internal_index(ec_data_flow_edges_t * data_flow_edges, sync_agent_ec_int task_index, sync_agent_ec_int param_index)
134 sync_agent_ec_int *child_task_param_start_index_array = data_flow_edges->child_task_param_start_index_array;
136 if (task_index == -1) {
141 return param_index + child_task_param_start_index_array[task_index];
145 sync_agent_ec_boolean ec_data_flow_edges_compute_task_index_and_param_index(ec_data_flow_edges_t * data_flow_edges, sync_agent_ec_int internal_index, sync_agent_ec_int * pTask_index, sync_agent_ec_int * pParam_index)
149 retvm_if(data_flow_edges == NULL, false, "ec_data_flow_edges_t is NULL !!");
151 sync_agent_ec_boolean valid_internal_index = false;
152 sync_agent_ec_int task_index = -1;
153 sync_agent_ec_int param_index = -1;
154 sync_agent_ec_int i = 0;
156 if (internal_index >= 0 && internal_index < data_flow_edges->total_param_cnt) {
157 valid_internal_index = true;
159 for (i = 0; i < data_flow_edges->child_task_cnt; i++) {
160 if (internal_index < data_flow_edges->child_task_param_start_index_array[i]) {
164 param_index = internal_index;
166 param_index = internal_index - data_flow_edges->child_task_param_start_index_array[i - 1];
172 if (i == data_flow_edges->child_task_cnt) {
174 param_index = internal_index - data_flow_edges->child_task_param_start_index_array[i - 1];
177 *pTask_index = task_index;
178 *pParam_index = param_index;
183 return valid_internal_index;
186 sync_agent_ec_boolean ec_data_flow_edges_add_edge(ec_data_flow_edges_t * data_flow_edges, sync_agent_ec_int from_task_index, sync_agent_ec_int from_param_index, sync_agent_ec_int to_task_index, sync_agent_ec_int to_param_index)
190 sync_agent_ec_boolean success = false;
192 sync_agent_ec_int from_param_internal_index = ec_data_flow_edges_compute_internal_index(data_flow_edges, from_task_index, from_param_index);
193 sync_agent_ec_int to_param_internal_index = ec_data_flow_edges_compute_internal_index(data_flow_edges, to_task_index, to_param_index);
196 if (data_flow_edges->from_param_array[to_param_internal_index] == -1) { /* -1 means no from param exist */
198 data_flow_edges->from_param_array[to_param_internal_index] = from_param_internal_index;
206 /* TODO : make this function accessible by other operation file */
207 sync_agent_ec_boolean ec_data_flow_edges_get_from_param_info(ec_data_flow_edges_t * data_flow_edges, sync_agent_ec_int to_task_index, sync_agent_ec_int to_param_index, sync_agent_ec_int * from_task_index, sync_agent_ec_int * from_param_index)
211 sync_agent_ec_boolean from_part_exist = false;
213 sync_agent_ec_int to_internal_index = ec_data_flow_edges_compute_internal_index(data_flow_edges, to_task_index, to_param_index);
214 sync_agent_ec_int from_internal_index = data_flow_edges->from_param_array[to_internal_index];
215 if (from_internal_index != -1) {
216 ec_data_flow_edges_compute_task_index_and_param_index(data_flow_edges, from_internal_index, from_task_index, from_param_index);
217 from_part_exist = true;
222 return from_part_exist;
225 sync_agent_ec_task_spec_s *ec_get_child_task_spec_from_child_task_info(ec_child_tasks_info_t * child_tasks_info, sync_agent_ec_uint child_task_index)
229 retvm_if(child_tasks_info == NULL, NULL, "ec_child_tasks_info_t is NULL !!");
231 if ( ((unsigned int)0 <= child_task_index) && (child_task_index < child_tasks_info->child_task_cnt)) {
233 return child_tasks_info->child_task_array[child_task_index];
239 sync_agent_ec_uint *ec_task_spec_duplicate_child_task_control_flow_in_degree(sync_agent_ec_task_spec_s * task_spec)
243 sync_agent_ec_uint *duplcated_child_task_control_flow_in_degree = NULL;
245 if (!ec_task_spec_is_container(task_spec)) {
249 ec_child_tasks_info_t *child_task_info = ec_task_spec_find_child_tasks_info(task_spec);
251 retvm_if(child_task_info == NULL, NULL, "ec_child_tasks_info_t is NULL !!");
253 sync_agent_ec_uint child_task_cnt = child_task_info->child_task_cnt;
254 sync_agent_ec_uint *child_task_control_flow_in_degree = child_task_info->child_task_control_flow_in_degree;
256 duplcated_child_task_control_flow_in_degree = (sync_agent_ec_uint *) malloc(child_task_cnt * sizeof(sync_agent_ec_uint));
257 if (duplcated_child_task_control_flow_in_degree == NULL) {
261 memcpy(duplcated_child_task_control_flow_in_degree, child_task_control_flow_in_degree, child_task_cnt * sizeof(sync_agent_ec_uint));
265 return duplcated_child_task_control_flow_in_degree;
272 sync_agent_ec_uint *ec_task_spec_duplicate_child_task_control_flow_in_degree_on_dynamic_case(sync_agent_ec_task_spec_s * dynamic_task_spec, sync_agent_ec_int dynamic_case)
276 sync_agent_ec_uint *duplcated_child_task_control_flow_in_degree = NULL;
278 if (!ec_task_spec_is_dynamic_container(dynamic_task_spec)) {
282 sync_agent_ec_uint child_task_cnt;
283 sync_agent_ec_uint *child_task_control_flow_in_degree;
285 ec_child_tasks_info_t *child_task_info = ec_task_spec_find_case_specific_child_tasks_info(dynamic_task_spec, dynamic_case);
286 if (child_task_info != NULL) {
287 child_task_cnt = child_task_info->child_task_cnt;
288 child_task_control_flow_in_degree = child_task_info->child_task_control_flow_in_degree;
293 duplcated_child_task_control_flow_in_degree = (sync_agent_ec_uint *) malloc(child_task_cnt * sizeof(sync_agent_ec_uint));
294 if (duplcated_child_task_control_flow_in_degree == NULL) {
298 memcpy(duplcated_child_task_control_flow_in_degree, child_task_control_flow_in_degree, child_task_cnt * sizeof(sync_agent_ec_uint));
302 return duplcated_child_task_control_flow_in_degree;
309 static sync_agent_ec_task_spec_s *_task_spec_new_default_task_spec(sync_agent_ec_char * task_name, sync_agent_ec_pointer post_task_func_usr_data, sync_agent_post_task_cb post_task_callback, sync_agent_ec_uint param_cnt,
310 sync_agent_ec_param_spec_s ** param_spec_array)
314 retvm_if(task_name == NULL, NULL, "sync_agent_ec_char is NULL !!");
317 sync_agent_ec_task_spec_s *task = NULL;
319 /* TODO : input parameter validation */
321 task = (sync_agent_ec_task_spec_s *) calloc(1, sizeof(sync_agent_ec_task_spec_s));
326 task->task_name = strdup(task_name);
327 if (task->task_name == NULL) {
331 task->task_param_spec_array = (sync_agent_ec_param_spec_s **) calloc(param_cnt, sizeof(sync_agent_ec_param_spec_s *));
332 if (task->task_param_spec_array == NULL) {
336 task->task_param_cnt = param_cnt;
337 for (i = 0; i < param_cnt; i++) {
338 task->task_param_spec_array[i] = ec_ref_param_spec(param_spec_array[i]);
341 task->usr_post_task_func_data = post_task_func_usr_data;
342 task->post_func = post_task_callback;
350 _task_spec_free_task_spec(task);
354 static void _task_spec_free_task_spec(sync_agent_ec_task_spec_s * task_spec)
358 if (task_spec != NULL) {
359 if (task_spec->task_name != NULL) {
360 free(task_spec->task_name);
363 if (task_spec->task_param_cnt > 0) {
365 for (i = 0; i < task_spec->task_param_cnt; i++) {
366 sync_agent_unref_param_spec(task_spec->task_param_spec_array[i]);
370 /* TODO : child_parallel_task_list when container task */
371 /* TODO : usr_task_data */
379 static ec_child_tasks_info_t *_task_spec_new_child_tasks_info(sync_agent_ec_uint parent_param_cnt, sync_agent_ec_uint child_task_cnt, sync_agent_ec_task_spec_s ** child_task_array)
383 sync_agent_ec_uint i = 0;
384 ec_child_tasks_info_t *child_task_info = (ec_child_tasks_info_t *) calloc(1, sizeof(ec_child_tasks_info_t));
385 if (child_task_info == NULL) {
386 _DEBUG_ERROR("CALLOC failed !!!");
390 child_task_info->child_task_cnt = child_task_cnt;
391 child_task_info->child_task_array = (sync_agent_ec_task_spec_s **) calloc(child_task_cnt, sizeof(sync_agent_ec_task_spec_s *));
392 if (child_task_info->child_task_array == NULL) {
396 for (i = 0; i < child_task_cnt; i++) {
397 child_task_info->child_task_array[i] = ec_task_spec_ref(child_task_array[i]);
400 child_task_info->child_task_control_flow_in_degree = (sync_agent_ec_uint *) calloc(child_task_cnt, sizeof(sync_agent_ec_uint));
401 if (child_task_info->child_task_control_flow_in_degree == NULL) {
405 child_task_info->control_edge_pool = ec_graph_edge_pool_new();
406 if (child_task_info->control_edge_pool == NULL) {
410 child_task_info->data_flow_edges = ec_data_flow_edges_new(parent_param_cnt, child_task_cnt, child_task_array);
411 if (child_task_info->data_flow_edges == NULL) {
417 return child_task_info;
420 __task_spec_free_child_tasks_info(child_task_info);
424 static void __task_spec_free_child_tasks_info(ec_child_tasks_info_t * child_task_info)
428 if (child_task_info != NULL) {
429 sync_agent_ec_uint cnt = child_task_info->child_task_cnt;
430 sync_agent_ec_uint i = 0;
432 if (child_task_info->data_flow_edges != NULL) {
433 ec_data_flow_edges_free(child_task_info->data_flow_edges);
436 if (child_task_info->control_edge_pool != NULL) {
437 ec_graph_edge_pool_free(child_task_info->control_edge_pool);
440 if (child_task_info->child_task_control_flow_in_degree != NULL) {
441 free(child_task_info->child_task_control_flow_in_degree);
444 if (child_task_info->child_task_array != NULL) {
445 for (i = 0; i < cnt; i++) {
446 ec_task_spec_unref(child_task_info->child_task_array[i]);
448 free(child_task_info->child_task_array);
451 free(child_task_info);
457 static ec_dynamic_container_task_specific_t *_task_spec_new_dynamic_container_task_specific(sync_agent_ec_uint parent_param_cnt, sync_agent_calculate_case_cb calculate_case_func, sync_agent_ec_uint case_cnt, sync_agent_ec_int * case_array,
458 sync_agent_ec_uint * child_task_cnt_array, sync_agent_ec_task_spec_s *** child_task_array_per_case_array)
462 retvm_if(case_array == NULL, NULL, "sync_agent_ec_int is NULL !!");
463 retvm_if(child_task_cnt_array == NULL, NULL, "sync_agent_ec_uint is NULL !!");
465 sync_agent_ec_uint i = 0;
466 ec_dynamic_container_task_specific_t *pDynamic_container_task_specific = (ec_dynamic_container_task_specific_t *) calloc(1, sizeof(ec_dynamic_container_task_specific_t));
467 if (pDynamic_container_task_specific == NULL) {
468 _DEBUG_ERROR("CALLOC failed !!!");
472 pDynamic_container_task_specific->calculate_case_func = calculate_case_func;
473 pDynamic_container_task_specific->case_cnt = case_cnt;
474 pDynamic_container_task_specific->case_array = (sync_agent_ec_int *) malloc(case_cnt * sizeof(sync_agent_ec_int));
475 if (pDynamic_container_task_specific->case_array == NULL) {
478 memcpy(pDynamic_container_task_specific->case_array, case_array, case_cnt * sizeof(sync_agent_ec_int));
480 pDynamic_container_task_specific->case_specific_child_task_info_array = (ec_child_tasks_info_t **) calloc(case_cnt, sizeof(ec_child_tasks_info_t *));
481 if (pDynamic_container_task_specific->case_specific_child_task_info_array == NULL) {
485 for (i = 0; i < case_cnt; i++) {
486 pDynamic_container_task_specific->case_specific_child_task_info_array[i] = _task_spec_new_child_tasks_info(parent_param_cnt, child_task_cnt_array[i], child_task_array_per_case_array[i]);
487 if (pDynamic_container_task_specific->case_specific_child_task_info_array[i] == NULL) {
494 return pDynamic_container_task_specific;
497 __task_spec_free_dynamic_container_task_specific(pDynamic_container_task_specific);
501 static void __task_spec_free_dynamic_container_task_specific(ec_dynamic_container_task_specific_t * pDynamic_container_task_specific)
505 if (pDynamic_container_task_specific != NULL) {
506 if (pDynamic_container_task_specific->case_array != NULL)
507 free(pDynamic_container_task_specific->case_array);
509 if (pDynamic_container_task_specific->case_specific_child_task_info_array != NULL && pDynamic_container_task_specific->case_cnt > 0) {
510 for (i = 0; i < pDynamic_container_task_specific->case_cnt; i++) {
511 __task_spec_free_child_tasks_info(pDynamic_container_task_specific->case_specific_child_task_info_array[i]);
513 free(pDynamic_container_task_specific->case_specific_child_task_info_array);
515 free(pDynamic_container_task_specific);
521 ec_child_tasks_info_t *ec_task_spec_find_child_tasks_info(sync_agent_ec_task_spec_s * parent_container_task_spec)
525 retvm_if(parent_container_task_spec == NULL, NULL, "sync_agent_ec_task_spec_s is NULL !!");
529 return parent_container_task_spec->u.container_task_specific;
532 ec_child_tasks_info_t *ec_task_spec_find_case_specific_child_tasks_info(sync_agent_ec_task_spec_s * parent_dynamic_task_spec, sync_agent_ec_int dynamic_case)
536 retvm_if(parent_dynamic_task_spec == NULL, NULL, "sync_agent_ec_task_spec_s is NULL !!");
538 ec_child_tasks_info_t *child_task_info = NULL;
540 ec_dynamic_container_task_specific_t *dynmaic_container_task_specific = parent_dynamic_task_spec->u.dynmaic_container_task_specific;
541 sync_agent_ec_uint case_cnt = dynmaic_container_task_specific->case_cnt;
542 sync_agent_ec_int *case_array = dynmaic_container_task_specific->case_array;
543 ec_child_tasks_info_t **case_specific_child_task_info_array = dynmaic_container_task_specific->case_specific_child_task_info_array;
545 sync_agent_ec_uint i = 0;
546 for (i = 0; i < case_cnt; i++) {
547 if (case_array[i] == dynamic_case) {
548 child_task_info = case_specific_child_task_info_array[i];
555 return child_task_info;
558 static sync_agent_ec_param_spec_s *__task_spec_find_param_spec(sync_agent_ec_task_spec_s * task_spec, sync_agent_ec_int param_index)
562 retvm_if(task_spec == NULL, NULL, "sync_agent_ec_task_spec_s is NULL !!");
564 sync_agent_ec_param_spec_s *pParam_spec = NULL;
565 sync_agent_ec_int param_cnt = ec_task_spec_get_param_cnt(task_spec);
566 sync_agent_ec_param_spec_s **param_spec_array = task_spec->task_param_spec_array;
568 if (param_index >= 0 && param_index < param_cnt) {
569 pParam_spec = param_spec_array[param_index];
577 static sync_agent_ec_error_e __task_spec_validate_container_task_spec(sync_agent_ec_task_spec_s * container_task_spec)
581 sync_agent_ec_error_e err = SYNC_AGENT_EC_OK;
582 if (container_task_spec == NULL) {
583 err = SYNC_AGENT_EC_INVALID_TASK;
587 if (container_task_spec->task_type != EC_TASK_CONTAINER) {
588 if (container_task_spec->task_type == EC_TASK_SIMPLE || container_task_spec->task_type == EC_TASK_DYNAMIC_CONTAINER) {
589 err = SYNC_AGENT_EC_MUST_USE_CONTAINER_TASK;
591 err = SYNC_AGENT_EC_INVALID_TASK;
602 static sync_agent_ec_error_e _task_spec_validate_dynamic_container_task_spec(sync_agent_ec_task_spec_s * dynamic_container_task_spec)
606 sync_agent_ec_error_e err = SYNC_AGENT_EC_OK;
607 if (dynamic_container_task_spec == NULL) {
608 err = SYNC_AGENT_EC_INVALID_TASK;
612 if (dynamic_container_task_spec->task_type != EC_TASK_DYNAMIC_CONTAINER) {
613 if (dynamic_container_task_spec->task_type == EC_TASK_SIMPLE || dynamic_container_task_spec->task_type == EC_TASK_CONTAINER) {
614 err = SYNC_AGENT_EC_MUST_USE_DYNAMIC_CONTAINER_TASK;
616 err = SYNC_AGENT_EC_INVALID_TASK;
628 sync_agent_ec_error_e task_spec_attach_queuing_rule_spec(sync_agent_ec_task_spec_s* spec, sync_agent_ec_queuing_rule_spec_s* queuing_rule_spec)
630 sync_agent_ec_error_e err = SYNC_AGENT_EC_OK;
631 GSList* listnode = g_slist_find(spec->queuing_rule_spec_list, queuing_rule_spec);
632 if (listnode != NULL) {
633 err = SYNC_AGENT_EC_DUPLICATE_QUEUING_RULE_SPEC;
637 spec->queuing_rule_spec_list = g_slist_prepend(spec->queuing_rule_spec_list, ec_ref_queuing_rule_spec(queuing_rule_spec));
644 sync_agent_ec_error_e ec_task_spec_valididate_child_task_index(sync_agent_ec_task_spec_s * container_task_spec, sync_agent_ec_int child_task_index)
648 sync_agent_ec_error_e err = SYNC_AGENT_EC_OK;
650 sync_agent_ec_task_spec_s *child_task_spec = ec_task_spec_get_child_task_spec(container_task_spec, child_task_index);
651 if (child_task_spec == NULL) {
652 err = SYNC_AGENT_EC_INVALID_CHILD_TASK_INDEX;
660 sync_agent_ec_error_e ec_task_spec_valididate_child_task_index_on_dynamic_case(sync_agent_ec_int dynamic_case, sync_agent_ec_task_spec_s * dynamic_container_task_spec, sync_agent_ec_int child_task_index)
664 sync_agent_ec_error_e err = SYNC_AGENT_EC_OK;
666 sync_agent_ec_task_spec_s *child_task_spec = ec_task_spec_get_child_task_spec_on_dynamic_case(dynamic_case,
667 dynamic_container_task_spec,
669 if (child_task_spec == NULL) {
670 err = SYNC_AGENT_EC_INVALID_CHILD_TASK_INDEX;
678 static sync_agent_ec_error_e __task_spec_validate_param_index(sync_agent_ec_task_spec_s * task_spec, sync_agent_ec_int param_index)
682 sync_agent_ec_error_e err = SYNC_AGENT_EC_OK;
684 sync_agent_ec_param_spec_s *pParam_spec = __task_spec_find_param_spec(task_spec, param_index);
685 if (pParam_spec == NULL) {
686 err = SYNC_AGENT_EC_INVALID_PARAM_INDEX;
694 static sync_agent_ec_error_e _task_spec_validate_set_control_flow_input_parameters(sync_agent_ec_task_spec_s * container_task_spec, sync_agent_ec_int from_task_index, sync_agent_ec_int to_task_index)
698 sync_agent_ec_error_e err = SYNC_AGENT_EC_OK;
700 err = __task_spec_validate_container_task_spec(container_task_spec);
701 if (err != SYNC_AGENT_EC_OK) {
705 err = ec_task_spec_valididate_child_task_index(container_task_spec, from_task_index);
706 if (err != SYNC_AGENT_EC_OK) {
710 err = ec_task_spec_valididate_child_task_index(container_task_spec, to_task_index);
718 static sync_agent_ec_error_e _task_spec_validate_set_control_flow_input_parameters_on_dynamic_case(sync_agent_ec_int dynamic_case, sync_agent_ec_task_spec_s * dynamic_container_task_spec, sync_agent_ec_int from_task_index, sync_agent_ec_int to_task_index)
722 sync_agent_ec_error_e err = SYNC_AGENT_EC_OK;
724 err = _task_spec_validate_dynamic_container_task_spec(dynamic_container_task_spec);
725 if (err != SYNC_AGENT_EC_OK) {
729 err = ec_task_spec_valididate_child_task_index_on_dynamic_case(dynamic_case, dynamic_container_task_spec, from_task_index);
730 if (err != SYNC_AGENT_EC_OK) {
734 err = ec_task_spec_valididate_child_task_index_on_dynamic_case(dynamic_case, dynamic_container_task_spec, to_task_index);
742 static sync_agent_ec_error_e _task_spec_validate_set_data_flow_input_parameters(sync_agent_ec_task_spec_s * container_task_spec, sync_agent_ec_int from_task_index, sync_agent_ec_int from_param_index, sync_agent_ec_int to_task_index,
743 sync_agent_ec_int to_param_index)
747 sync_agent_ec_error_e err = SYNC_AGENT_EC_OK;
749 err = __task_spec_validate_container_task_spec(container_task_spec);
750 if (err != SYNC_AGENT_EC_OK) {
754 sync_agent_ec_task_spec_s *pFrom_task_spec = NULL;
755 sync_agent_ec_task_spec_s *pTo_task_spec = NULL;
756 if (from_task_index != -1) {
757 err = ec_task_spec_valididate_child_task_index(container_task_spec, from_task_index);
758 if (err != SYNC_AGENT_EC_OK) {
762 pFrom_task_spec = ec_task_spec_get_child_task_spec(container_task_spec, from_task_index);
764 pFrom_task_spec = container_task_spec;
766 err = __task_spec_validate_param_index(pFrom_task_spec, from_param_index);
767 if (err != SYNC_AGENT_EC_OK) {
771 if (to_task_index != -1) {
772 err = ec_task_spec_valididate_child_task_index(container_task_spec, to_task_index);
773 if (err != SYNC_AGENT_EC_OK) {
777 pTo_task_spec = ec_task_spec_get_child_task_spec(container_task_spec, to_task_index);
779 pTo_task_spec = container_task_spec;
781 err = __task_spec_validate_param_index(pTo_task_spec, to_param_index);
789 static sync_agent_ec_error_e _task_spec_validate_set_data_flow_input_parameters_on_dynamic_case(sync_agent_ec_int dynamic_case, sync_agent_ec_task_spec_s * dynamic_container_task_spec, sync_agent_ec_int from_task_index, sync_agent_ec_int from_param_index,
790 sync_agent_ec_int to_task_index, sync_agent_ec_int to_param_index)
794 sync_agent_ec_error_e err = SYNC_AGENT_EC_OK;
796 err = _task_spec_validate_dynamic_container_task_spec(dynamic_container_task_spec);
797 if (err != SYNC_AGENT_EC_OK) {
801 sync_agent_ec_task_spec_s *pFrom_task_spec = NULL;
802 sync_agent_ec_task_spec_s *pTo_task_spec = NULL;
803 if (from_task_index != -1) {
804 err = ec_task_spec_valididate_child_task_index_on_dynamic_case(dynamic_case, dynamic_container_task_spec, from_task_index);
805 if (err != SYNC_AGENT_EC_OK) {
809 pFrom_task_spec = ec_task_spec_get_child_task_spec_on_dynamic_case(dynamic_case, dynamic_container_task_spec, from_task_index);
811 pFrom_task_spec = dynamic_container_task_spec;
813 err = __task_spec_validate_param_index(pFrom_task_spec, from_param_index);
814 if (err != SYNC_AGENT_EC_OK) {
818 if (to_task_index != -1) {
819 err = ec_task_spec_valididate_child_task_index_on_dynamic_case(dynamic_case, dynamic_container_task_spec, to_task_index);
820 if (err != SYNC_AGENT_EC_OK) {
824 pTo_task_spec = ec_task_spec_get_child_task_spec_on_dynamic_case(dynamic_case, dynamic_container_task_spec, to_task_index);
826 pTo_task_spec = dynamic_container_task_spec;
828 err = __task_spec_validate_param_index(pTo_task_spec, to_param_index);
836 EXPORT_API sync_agent_ec_task_spec_s *sync_agent_alloc_simple_task_spec(sync_agent_ec_char * task_name, sync_agent_task_process_cb task_process, sync_agent_ec_pointer post_task_func_usr_data, sync_agent_post_task_cb post_task_callback,
837 sync_agent_ec_uint param_cnt, sync_agent_ec_param_spec_s ** param_spec_array)
841 sync_agent_ec_task_spec_s *task = NULL;
843 task = _task_spec_new_default_task_spec(task_name, post_task_func_usr_data, post_task_callback, param_cnt, param_spec_array);
848 task->task_type = EC_TASK_SIMPLE;
849 task->u.task_process = task_process;
856 sync_agent_ec_task_spec_s *ec_task_spec_ref(sync_agent_ec_task_spec_s * task_spec)
860 if (task_spec == NULL) {
864 g_atomic_int_inc(&(task_spec->ref_count));
871 void ec_task_spec_unref(sync_agent_ec_task_spec_s * task_spec)
875 if (task_spec == NULL) {
879 if (g_atomic_int_dec_and_test(&(task_spec->ref_count))) {
880 _task_spec_free_task_spec(task_spec);
886 sync_agent_ec_boolean ec_task_spec_is_same(sync_agent_ec_task_spec_s * task_spec1, sync_agent_ec_task_spec_s * task_spec2)
890 if (task_spec1 == task_spec2) {
898 sync_agent_ec_boolean ec_task_spec_is_simple(sync_agent_ec_task_spec_s * task_spec)
902 if (task_spec == NULL) {
903 _DEBUG_INFO("task_spec == NULL\n");
907 if (task_spec->task_type == EC_TASK_SIMPLE) {
916 sync_agent_ec_boolean ec_task_spec_is_container(sync_agent_ec_task_spec_s * task_spec)
920 if (task_spec == NULL) {
921 _DEBUG_INFO("task_spec == NULL\n");
925 if (task_spec->task_type == EC_TASK_CONTAINER) {
934 sync_agent_ec_boolean ec_task_spec_is_dynamic_container(sync_agent_ec_task_spec_s * task_spec)
938 if (task_spec == NULL) {
939 _DEBUG_INFO("task_spec == NULL\n");
943 if (task_spec->task_type == EC_TASK_DYNAMIC_CONTAINER) {
952 sync_agent_ec_uint ec_task_spec_get_child_task_cnt(sync_agent_ec_task_spec_s * task_spec)
956 if (ec_task_spec_is_container(task_spec)) {
958 return task_spec->u.container_task_specific->child_task_cnt;
965 sync_agent_ec_task_spec_s *ec_task_spec_get_child_task_spec(sync_agent_ec_task_spec_s * parent_task_spec, sync_agent_ec_int child_task_index)
969 sync_agent_ec_task_spec_s *child_task_spec = NULL;
971 ec_child_tasks_info_t *child_task_info = ec_task_spec_find_child_tasks_info(parent_task_spec);
973 retvm_if(child_task_info == NULL, NULL, "ec_child_tasks_info_t is NULL !!");
975 child_task_spec = ec_get_child_task_spec_from_child_task_info(child_task_info, child_task_index);
979 return child_task_spec;
982 sync_agent_ec_uint ec_task_spec_get_child_task_cnt_on_dynamic_case(sync_agent_ec_task_spec_s * dynamic_task_spec, sync_agent_ec_int dynamic_case)
986 if (ec_task_spec_is_dynamic_container(dynamic_task_spec)) {
987 ec_child_tasks_info_t *child_task_info = ec_task_spec_find_case_specific_child_tasks_info(dynamic_task_spec, dynamic_case);
988 if (child_task_info != NULL) {
990 return child_task_info->child_task_cnt;
1001 sync_agent_ec_task_spec_s *ec_task_spec_get_child_task_spec_on_dynamic_case(sync_agent_ec_int dynamic_case, sync_agent_ec_task_spec_s * parent_dynamic_task_spec, sync_agent_ec_int child_task_index)
1005 sync_agent_ec_task_spec_s *child_task_spec = NULL;
1007 sync_agent_ec_error_e ec_error = _task_spec_validate_dynamic_container_task_spec(parent_dynamic_task_spec);
1008 if (ec_error != SYNC_AGENT_EC_OK) {
1012 ec_child_tasks_info_t *child_task_info = ec_task_spec_find_case_specific_child_tasks_info(parent_dynamic_task_spec, dynamic_case);
1013 child_task_spec = ec_get_child_task_spec_from_child_task_info(child_task_info, child_task_index);
1017 return child_task_spec;
1023 sync_agent_ec_int ec_task_spec_get_param_cnt(sync_agent_ec_task_spec_s * task_spec)
1029 return task_spec->task_param_cnt;
1032 sync_agent_calculate_case_cb ec_task_spec_get_calculate_case_callback_func(sync_agent_ec_task_spec_s * dynamic_container_task_spec)
1036 retvm_if(dynamic_container_task_spec == NULL, NULL, "sync_agent_ec_task_spec_s is NULL !!");
1040 return dynamic_container_task_spec->u.dynmaic_container_task_specific->calculate_case_func;
1043 sync_agent_ec_boolean ec_task_spec_get_output_param_info(sync_agent_ec_task_spec_s * task_spec, sync_agent_ec_int * output_param_cnt, sync_agent_ec_int ** output_param_index_array)
1047 if (task_spec == NULL || output_param_cnt == NULL || output_param_index_array == NULL) {
1051 sync_agent_ec_int i = 0;
1052 sync_agent_ec_int param_cnt = ec_task_spec_get_param_cnt(task_spec);
1053 sync_agent_ec_param_spec_s **task_param_spec_array = task_spec->task_param_spec_array;
1055 sync_agent_ec_int output_param_count = 0;
1056 sync_agent_ec_int *output_param_index_arr = NULL;
1057 output_param_index_arr = (sync_agent_ec_int *) calloc(param_cnt, sizeof(sync_agent_ec_int));
1058 if (output_param_index_arr == NULL) {
1062 sync_agent_ec_param_spec_s *pParam_spec = NULL;
1063 for (i = 0; i < param_cnt; i++) {
1064 pParam_spec = task_param_spec_array[i];
1065 if (ec_param_is_output_flag_on(pParam_spec->flags)) {
1066 output_param_index_arr[output_param_count] = i;
1067 output_param_count++;
1071 *output_param_cnt = output_param_count;
1072 *output_param_index_array = output_param_index_arr;
1082 sync_agent_ec_task_spec_s *ec_alloc_container_task_spec_outline(sync_agent_ec_char * task_name, sync_agent_ec_pointer usr_post_task_func_data, sync_agent_post_task_cb post_func, sync_agent_ec_uint param_cnt, sync_agent_ec_param_spec_s ** param_spec_array,
1083 sync_agent_ec_uint child_task_cnt, sync_agent_ec_task_spec_s ** child_task_array)
1087 sync_agent_ec_task_spec_s *task_spec = NULL;
1089 task_spec = _task_spec_new_default_task_spec(task_name, usr_post_task_func_data, post_func, param_cnt, param_spec_array);
1091 if (task_spec == NULL) {
1094 task_spec->task_type = EC_TASK_CONTAINER;
1095 task_spec->u.container_task_specific = _task_spec_new_child_tasks_info(param_cnt, child_task_cnt, child_task_array);
1097 if (task_spec->u.container_task_specific == NULL) {
1106 _task_spec_free_task_spec(task_spec);
1110 sync_agent_ec_error_e ec_set_data_flow(sync_agent_ec_task_spec_s * container_task_spec, sync_agent_ec_int from_task_index, sync_agent_ec_int from_param_index, sync_agent_ec_int to_task_index, sync_agent_ec_int to_param_index)
1114 sync_agent_ec_error_e err = SYNC_AGENT_EC_OK;
1117 err = _task_spec_validate_set_data_flow_input_parameters(container_task_spec, from_task_index, from_param_index, to_task_index, to_param_index);
1118 if (err != SYNC_AGENT_EC_OK) {
1122 if (from_task_index != -1 && to_task_index != -1) {
1123 /* add control flow */
1124 err = ec_set_control_flow(container_task_spec, from_task_index, to_task_index);
1125 if (err != SYNC_AGENT_EC_OK) {
1131 ec_child_tasks_info_t *child_task_info = ec_task_spec_find_child_tasks_info(container_task_spec);
1132 ec_data_flow_edges_t *data_flow_edges = child_task_info->data_flow_edges;
1133 if (!ec_data_flow_edges_add_edge(data_flow_edges, from_task_index, from_param_index, to_task_index, to_param_index)) {
1134 err = SYNC_AGENT_EC_DUPLICATE_DATA_FLOW_EDGE;
1143 sync_agent_ec_error_e ec_set_data_flow_on_dynamic_case(sync_agent_ec_int dynamic_case, sync_agent_ec_task_spec_s * dynamic_container_task_spec, sync_agent_ec_int from_task_index, sync_agent_ec_int from_param_index, sync_agent_ec_int to_task_index,
1144 sync_agent_ec_int to_param_index)
1148 sync_agent_ec_error_e err = SYNC_AGENT_EC_OK;
1151 err = _task_spec_validate_set_data_flow_input_parameters_on_dynamic_case(dynamic_case, dynamic_container_task_spec, from_task_index, from_param_index, to_task_index, to_param_index);
1152 if (err != SYNC_AGENT_EC_OK) {
1156 if (from_task_index != -1 && to_task_index != -1) {
1157 /* add control flow */
1158 err = ec_task_spec_set_control_flow_on_dynamic_case(dynamic_case, dynamic_container_task_spec, from_task_index, to_task_index);
1159 if (err != SYNC_AGENT_EC_OK) {
1165 ec_data_flow_edges_t *data_flow_edges;
1166 ec_child_tasks_info_t *child_task_info = ec_task_spec_find_case_specific_child_tasks_info(dynamic_container_task_spec, dynamic_case);
1167 if (child_task_info != NULL) {
1168 data_flow_edges = child_task_info->data_flow_edges;
1170 err = SYNC_AGENT_EC_INVALID_TASK;
1173 if (!ec_data_flow_edges_add_edge(data_flow_edges, from_task_index, from_param_index, to_task_index, to_param_index)) {
1174 err = SYNC_AGENT_EC_DUPLICATE_DATA_FLOW_EDGE;
1183 sync_agent_ec_error_e ec_set_control_flow(sync_agent_ec_task_spec_s * container_task_spec, sync_agent_ec_int from_task_index, sync_agent_ec_int to_task_index)
1187 sync_agent_ec_error_e err = SYNC_AGENT_EC_OK;
1189 err = _task_spec_validate_set_control_flow_input_parameters(container_task_spec, from_task_index, to_task_index);
1190 if (err != SYNC_AGENT_EC_OK) {
1194 ec_child_tasks_info_t *child_task_info = ec_task_spec_find_child_tasks_info(container_task_spec);
1195 ec_graph_edge_pool_t *control_edge_pool = child_task_info->control_edge_pool;
1196 sync_agent_ec_uint *control_flow_in_degree_array = child_task_info->child_task_control_flow_in_degree;
1198 /* add edge and in_degree count */
1199 if (ec_graph_edge_pool_add_edge(control_edge_pool, (sync_agent_ec_constpointer) ((intptr_t)from_task_index), (sync_agent_ec_constpointer) ((intptr_t)to_task_index))) {
1200 control_flow_in_degree_array[to_task_index]++;
1209 sync_agent_ec_error_e ec_task_spec_set_control_flow_on_dynamic_case(sync_agent_ec_int dynamic_case, sync_agent_ec_task_spec_s * dynamic_container_task_spec, sync_agent_ec_int from_task_index, sync_agent_ec_int to_task_index)
1213 sync_agent_ec_error_e err = SYNC_AGENT_EC_OK;
1215 err = _task_spec_validate_set_control_flow_input_parameters_on_dynamic_case(dynamic_case, dynamic_container_task_spec, from_task_index, to_task_index);
1216 if (err != SYNC_AGENT_EC_OK) {
1220 ec_graph_edge_pool_t *control_edge_pool;
1221 ec_child_tasks_info_t *child_task_info = ec_task_spec_find_case_specific_child_tasks_info(dynamic_container_task_spec, dynamic_case);
1222 if (child_task_info != NULL) {
1223 control_edge_pool = child_task_info->control_edge_pool;
1225 err = SYNC_AGENT_EC_INVALID_TASK;
1228 sync_agent_ec_uint *control_flow_in_degree_array = child_task_info->child_task_control_flow_in_degree;
1230 /* add edge and in_degree count */
1231 if (ec_graph_edge_pool_add_edge(control_edge_pool, (sync_agent_ec_constpointer) ((intptr_t)from_task_index), (sync_agent_ec_constpointer) ((intptr_t)to_task_index))) {
1232 control_flow_in_degree_array[to_task_index]++;
1241 sync_agent_ec_task_spec_s *ec_alloc_dynamic_container_task_spec_outline(sync_agent_ec_char * task_name, sync_agent_ec_pointer usr_post_task_func_data, sync_agent_post_task_cb post_func, sync_agent_ec_uint param_cnt,
1242 sync_agent_ec_param_spec_s ** param_spec_array, sync_agent_calculate_case_cb calculate_case_func, sync_agent_ec_uint case_cnt, sync_agent_ec_int * case_array,
1243 sync_agent_ec_uint * child_task_cnt_array, sync_agent_ec_task_spec_s *** child_task_array_per_case_array)
1247 sync_agent_ec_task_spec_s *task_spec = NULL;
1249 task_spec = _task_spec_new_default_task_spec(task_name, usr_post_task_func_data, post_func, param_cnt, param_spec_array);
1251 if (task_spec == NULL) {
1254 task_spec->task_type = EC_TASK_DYNAMIC_CONTAINER;
1255 task_spec->u.dynmaic_container_task_specific = _task_spec_new_dynamic_container_task_specific(param_cnt, calculate_case_func, case_cnt, case_array, child_task_cnt_array, child_task_array_per_case_array);
1257 if (task_spec->u.dynmaic_container_task_specific == NULL) {
1266 _task_spec_free_task_spec(task_spec);