Commit 92b54f5b authored by Maxime Perrotin's avatar Maxime Perrotin
Browse files

Allow multiple timers with the same name

parent 82c88e88
Pipeline #370 skipped
...@@ -504,70 +504,125 @@ void add_RI_to_ada_wrappers(Interface * i) ...@@ -504,70 +504,125 @@ void add_RI_to_ada_wrappers(Interface * i)
fprintf(b, "%s", qgen_args); fprintf(b, "%s", qgen_args);
fprintf(b, ");\n\n"); fprintf(b, ");\n\n");
} else { }
else {
if (asynch == i->synchronism) { if (asynch == i->synchronism) {
/* /*
* Distant FV is a thread (asynchronous RI). This means that depending on the nature of the current FV (thread or passive) * Distant FV is a thread (asynchronous RI). This means that depending on the nature of the current FV (thread or passive)
* we have either to call the VM (if we are in a thread) or to switch-case the caller thread to call his own access to the VM * we have either to call the VM (if we are in a thread) or to switch-case the caller thread to call his own access to the VM
* We retrieve the caller thread ID using the "stack" * We retrieve the caller thread ID using the "stack"
*/ */
if (thread_runtime == i->parent_fv->runtime_nature) { if (thread_runtime == i->parent_fv->runtime_nature) {
fprintf(b, "\t\tValue: %s%s%s_%s_others_Interface \n\t\t(%s%s%s_%s_others_Port_Type'(OUTPORT_%s));\n", (get_context()->aadlv2) ? i->parent_fv->name : "", // AADL v2 only fprintf(b, "\t\tValue: %s%s%s_%s_others_Interface \n\t\t(%s%s%s_%s_others_Port_Type'(OUTPORT_%s));\n", (get_context()->aadlv2) ? i->parent_fv->name : "", // AADL v2 only
(get_context()->aadlv2) ? "_CV_Thread_" : "", // AADL v2 only (get_context()->aadlv2) ? "_CV_Thread_" : "", // AADL v2 only
i->parent_fv->name, // fv->name should be replaced by the namespace (not supported 15/07/2009) (used to be aplc) i->parent_fv->name, // fv->name should be replaced by the namespace (not supported 15/07/2009) (used to be aplc)
i->parent_fv->name, (get_context()->aadlv2) ? i->parent_fv->name : "", // AADL v2 only i->parent_fv->name, (get_context()->aadlv2) ? i->parent_fv->name : "", // AADL v2 only
(get_context()->aadlv2) ? "_CV_Thread_" : "", // AADL v2 only (get_context()->aadlv2) ? "_CV_Thread_" : "", // AADL v2 only
i->parent_fv->name, // fv->name should be replaced by the namespace (not supported 15/07/2009) (used to be aplc) i->parent_fv->name, // fv->name should be replaced by the namespace (not supported 15/07/2009) (used to be aplc)
i->parent_fv->name, i->name); i->parent_fv->name, i->name);
fprintf(b,
"\t\tErr: PolyORB_HI.Errors.Error_Kind;\n\t\tuse type PolyORB_HI.Errors.Error_Kind;\n");
fprintf(b, "\tbegin\n");
/* Copy the buffer(s) from C to Ada */
if (NULL != i->in) {
tmp = i->in;
while (NULL != tmp) {
fprintf(b, "\t\tfor J in 1 .. IN_%s_size loop\n",
tmp->value->name);
fprintf(b, fprintf(b,
"\t\t\tValue.OUTPORT_%s_DATA.Buffer (J) := PolyORB_HI_Generated.Types.Stream_Element%s\n", "\t\tErr: PolyORB_HI.Errors.Error_Kind;\n\t\tuse type PolyORB_HI.Errors.Error_Kind;\n");
i->name, fprintf(b, "\tbegin\n");
get_context()->aadlv2?"_Buffer":""); /* Copy the buffer(s) from C to Ada */
fprintf(b, if (NULL != i->in) {
"\t\t\t\t(IN_%s (Interfaces.C.size_t (J - 1)));\n", tmp = i->in;
tmp->value->name); while (NULL != tmp) {
fprintf(b, "\t\tend loop;\n"); fprintf(b, "\t\tfor J in 1 .. IN_%s_size loop\n",
if (!(get_context()->aadlv2)) tmp->value->name);
fprintf(b, "\t\tValue.OUTPORT_%s_DATA.Length := PolyORB_HI_Generated.Types.uint16 (IN_%s_size);\n", // old V1 fprintf(b,
i->name, tmp->value->name); "\t\t\tValue.OUTPORT_%s_DATA.Buffer (J) := PolyORB_HI_Generated.Types.Stream_Element%s\n",
else i->name,
fprintf(b, "\t\tValue.OUTPORT_%s_DATA.Length := PolyORB_HI_Generated.Types.Unsigned_16 (IN_%s_size);\n", // AADL V2, should work with V1 but not supported by Ocarina yet also, otherwise put back previous line for V1 get_context()->aadlv2?"_Buffer":"");
i->name, tmp->value->name); fprintf(b,
tmp = tmp->next; "\t\t\t\t(IN_%s (Interfaces.C.size_t (J - 1)));\n",
} tmp->value->name);
fprintf(b, "\t\tend loop;\n");
if (!(get_context()->aadlv2))
fprintf(b, "\t\tValue.OUTPORT_%s_DATA.Length := PolyORB_HI_Generated.Types.uint16 (IN_%s_size);\n", // old V1
i->name, tmp->value->name);
else
fprintf(b, "\t\tValue.OUTPORT_%s_DATA.Length := PolyORB_HI_Generated.Types.Unsigned_16 (IN_%s_size);\n", // AADL V2, should work with V1 but not supported by Ocarina yet also, otherwise put back previous line for V1
i->name, tmp->value->name);
tmp = tmp->next;
}
}
if (NULL != i->parent_fv->process) {
fprintf(b, "\t\tPut_Value (%s_%s_K, Value);\n",
i->parent_fv->process->identifier,
i->parent_fv->name);
/* Following is added only for the Backdoor backend : call the Send_Output to
flush immediately the output buffer */
fprintf(b, "\t\tErr:=Send_Output(%s_%s_K, %s%s%s_%s_others_Port_Type'(OUTPORT_%s));\n", i->parent_fv->process->identifier, i->parent_fv->name, (get_context()->aadlv2) ? i->parent_fv->name : "", // AADL v2 only
(get_context()->aadlv2) ? "_CV_Thread_" : "", // AADL v2 only
i->parent_fv->name, // fv->name should be replaced by the namespace (not supported 15/07/2009) (used to be aplc)
i->parent_fv->name, i->name);
}
} }
else { // Current FV = Passive function
fprintf(b, "\tbegin\n");
fprintf(b,
"\t\t -- This function is passive, thus not have direct access to the VM\n");
fprintf(b,
"\t\t -- It must use its calling thread to invoke this asynchronous RI\n\n");
/* Build the list of calling threads for this RI */
FV_list *calltmp = NULL;
if (NULL == i->calling_pis) calltmp = i->parent_fv->calling_threads;
else {
FOREACH(calling_pi, Interface, i->calling_pis, {
FOREACH(thread_caller, FV, calling_pi->calling_threads, {
ADD_TO_SET(FV, calltmp, thread_caller);
});
});
}
/* Count the number of calling threads */
FOREACH(ct, FV, calltmp, {
(void) ct;
count ++;
});
if (NULL != i->parent_fv->process) { if (1 == count) {
fprintf(b, "\t\tPut_Value (%s_%s_K, Value);\n", fprintf(b, "\t\t%s_async_ri_wrappers.vm_%s_vt",
i->parent_fv->process->identifier, calltmp->value->name,
i->parent_fv->name); i->name);
/* Following is added only for the Backdoor backend : call the Send_Output to if (NULL != i->in) { // Add parameters
flush immediately the output buffer */ fprintf(b, "(");
fprintf(b, "\t\tErr:=Send_Output(%s_%s_K, %s%s%s_%s_others_Port_Type'(OUTPORT_%s));\n", i->parent_fv->process->identifier, i->parent_fv->name, (get_context()->aadlv2) ? i->parent_fv->name : "", // AADL v2 only FOREACH(p, Parameter, i->in, {
(get_context()->aadlv2) ? "_CV_Thread_" : "", // AADL v2 only List_Ada_Param_Names(p, &b);
i->parent_fv->name, // fv->name should be replaced by the namespace (not supported 15/07/2009) (used to be aplc) });
i->parent_fv->name, i->name); fprintf(b, ")");
}
fprintf(b, ";\n");
}
else if (count > 1) {
fprintf(b, "\t\tcase callinglist.get_top_value is\n");
FOREACH(caller, FV, calltmp, {
fprintf(b,
"\t\t\twhen %d => %s_async_ri_wrappers.vm_%s_vt",
caller->thread_id,
caller->name, i->name);
if (NULL != i->in) { // Add parameters
fprintf(b, "(");
FOREACH(p, Parameter, i->in, {
List_Ada_Param_Names(p, &b);
});
fprintf(b, ")");
}
fprintf(b, ";\n");
});
fprintf(b, "\t\t\twhen others => null;\n");
fprintf(b, "\t\tend case;\n");
}
} }
} }
else { // Current FV = Passive function else {
fprintf(b, "\tbegin\n");
fprintf(b,
"\t\t -- This function is passive, thus not have direct access to the VM\n");
fprintf(b,
"\t\t -- It must use its calling thread to invoke this asynchronous RI\n\n");
/* Build the list of calling threads for this RI */ /* Build the list of calling threads for this RI */
FV_list *calltmp = NULL; FV_list *calltmp = NULL;
if (NULL == i->calling_pis) calltmp = i->parent_fv->calling_threads; if (NULL == i->calling_pis) calltmp = i->parent_fv->calling_threads;
...@@ -585,49 +640,6 @@ void add_RI_to_ada_wrappers(Interface * i) ...@@ -585,49 +640,6 @@ void add_RI_to_ada_wrappers(Interface * i)
count ++; count ++;
}); });
if (1 == count) {
fprintf(b, "\t\t%s_async_ri_wrappers.vm_%s_vt",
calltmp->value->name,
i->name);
if (NULL != i->in) { // Add parameters
fprintf(b, "(");
FOREACH(p, Parameter, i->in, {
List_Ada_Param_Names(p, &b);
});
fprintf(b, ")");
}
fprintf(b, ";\n");
}
else if (count > 1) {
fprintf(b, "\t\tcase callinglist.get_top_value is\n");
FOREACH(caller, FV, calltmp, {
fprintf(b,
"\t\t\twhen %d => %s_async_ri_wrappers.vm_%s_vt",
caller->thread_id,
caller->name, i->name);
if (NULL != i->in) { // Add parameters
fprintf(b, "(");
FOREACH(p, Parameter, i->in, {
List_Ada_Param_Names(p, &b);
});
fprintf(b, ")");
}
fprintf(b, ";\n");
});
fprintf(b, "\t\t\twhen others => null;\n");
fprintf(b, "\t\tend case;\n");
}
}
}
else {
int cnt = 0;
FOREACH(t, FV, i->parent_fv->calling_threads, {
(void) t;
cnt++;
})
fprintf(b, "\tbegin\n"); fprintf(b, "\tbegin\n");
if (protected == i->rcm) { if (protected == i->rcm) {
...@@ -638,13 +650,13 @@ void add_RI_to_ada_wrappers(Interface * i) ...@@ -638,13 +650,13 @@ void add_RI_to_ada_wrappers(Interface * i)
} }
if (passive_runtime == i->parent_fv->runtime_nature) { if (passive_runtime == i->parent_fv->runtime_nature) {
if (cnt > 1) { if (count > 1) {
fprintf(b, "callinglist.get_top_value"); fprintf(b, "callinglist.get_top_value");
} }
else if (1 == cnt) { else if (1 == count) {
fprintf(b, "%d", i->parent_fv->calling_threads->value->thread_id); fprintf(b, "%d", calltmp->value->thread_id);
} }
else if (0 == cnt) { else if (0 == count) {
ERROR ("** Error: function \"%s\" is not called by anyone (dead code)!\n", i->parent_fv->name); ERROR ("** Error: function \"%s\" is not called by anyone (dead code)!\n", i->parent_fv->name);
ERROR ("** This is not supported by the Ada runtime. You may have to change two things:\n"); ERROR ("** This is not supported by the Ada runtime. You may have to change two things:\n");
ERROR ("** 1) (In any case) use the -p flag when calling the TASTE orchestrator, and\n"); ERROR ("** 1) (In any case) use the -p flag when calling the TASTE orchestrator, and\n");
......
...@@ -538,13 +538,28 @@ void add_RI_to_c_wrappers(Interface * i) ...@@ -538,13 +538,28 @@ void add_RI_to_c_wrappers(Interface * i)
} }
} }
else { /* synch==i->synchronism (RI is synchronous) : else { /* synch==i->synchronism (RI is synchronous) :
make a direct call to the remote function make a direct call to the remote function
defined in remote polyorb_interface.c, defined in remote polyorb_interface.c,
and pass the thread id as parameter */ and pass the thread id as parameter */
int count = 0; int count = 0;
FOREACH(t, FV, i->parent_fv->calling_threads, {
(void) t; count++;}); /* Build the list of calling threads for this RI */
FV_list *calltmp = NULL;
if (NULL == i->calling_pis) calltmp = i->parent_fv->calling_threads;
else {
FOREACH(calling_pi, Interface, i->calling_pis, {
FOREACH(thread_caller, FV, calling_pi->calling_threads, {
ADD_TO_SET(FV, calltmp, thread_caller);
});
});
}
/* Count the number of calling threads */
FOREACH(ct, FV, calltmp, {
(void) ct;
count ++;
});
fprintf(b, "\tsync_%s_%s(", i->distant_fv, fprintf(b, "\tsync_%s_%s(", i->distant_fv,
NULL != i->distant_name ? i->distant_name : i->name); NULL != i->distant_name ? i->distant_name : i->name);
...@@ -554,8 +569,7 @@ void add_RI_to_c_wrappers(Interface * i) ...@@ -554,8 +569,7 @@ void add_RI_to_c_wrappers(Interface * i)
fprintf(b, "%s_callinglist_get_top_value()", fprintf(b, "%s_callinglist_get_top_value()",
i->parent_fv->name); i->parent_fv->name);
} else if (1 == count) { } else if (1 == count) {
fprintf(b, "%d", fprintf(b, "%d", calltmp->value->thread_id);
i->parent_fv->calling_threads->value->thread_id);
} else if (0 == count) { } else if (0 == count) {
printf printf
("Warning: function \"%s\" is not called by anyone (dead code)!\n", ("Warning: function \"%s\" is not called by anyone (dead code)!\n",
......
...@@ -186,9 +186,11 @@ void Add_timers_to_function (FV *fv, FV *timer_manager) ...@@ -186,9 +186,11 @@ void Add_timers_to_function (FV *fv, FV *timer_manager)
FOREACH (timer, String, fv->timer_list, { FOREACH (timer, String, fv->timer_list, {
/* Declare functions in timer manager code */ /* Declare functions in timer manager code */
fprintf (header, "void %s_PI_SET_%s(const asn1SccT_UInt32 *val);\n\n", fprintf (header, "void %s_PI_%s_SET_%s(const asn1SccT_UInt32 *val);\n\n",
timer_manager->name, timer); timer_manager->name,
fprintf (code, "void %s_PI_SET_%s(const asn1SccT_UInt32 *val)\n" fv->name,
timer);
fprintf (code, "void %s_PI_%s_SET_%s(const asn1SccT_UInt32 *val)\n"
"{\n" "{\n"
" /* Timer value must be multiple of 100 ms */\n" " /* Timer value must be multiple of 100 ms */\n"
" assert (*val %% 100 == 0);\n" " assert (*val %% 100 == 0);\n"
...@@ -196,18 +198,22 @@ void Add_timers_to_function (FV *fv, FV *timer_manager) ...@@ -196,18 +198,22 @@ void Add_timers_to_function (FV *fv, FV *timer_manager)
" timers[%s_%s].value = *val / 100;\n" " timers[%s_%s].value = *val / 100;\n"
"}\n\n", "}\n\n",
timer_manager->name, timer_manager->name,
fv->name,
timer, timer,
fv->name, fv->name,
timer, timer,
fv->name, fv->name,
timer); timer);
fprintf (header, "void %s_PI_RESET_%s();\n\n", fprintf (header, "void %s_PI_%s_RESET_%s();\n\n",
timer_manager->name, timer); timer_manager->name,
fprintf (code, "void %s_PI_RESET_%s()\n" fv->name,
timer);
fprintf (code, "void %s_PI_%s_RESET_%s()\n"
"{\n" "{\n"
" timers[%s_%s].state = inactive;\n" " timers[%s_%s].state = inactive;\n"
"}\n\n", "}\n\n",
timer_manager->name, timer_manager->name,
fv->name,
timer, timer,
fv->name, fv->name,
timer); timer);
...@@ -242,9 +248,11 @@ void Add_timers_to_function (FV *fv, FV *timer_manager) ...@@ -242,9 +248,11 @@ void Add_timers_to_function (FV *fv, FV *timer_manager)
/* Add Unpro PI "RESET_timer" to timer manager (no param) */ /* Add Unpro PI "RESET_timer" to timer manager (no param) */
reset_timer = Duplicate_Interface (PI, expire, timer_manager); reset_timer = Duplicate_Interface (PI, expire, timer_manager);
free (reset_timer->name); free (reset_timer->name);
reset_timer->name = make_string ("RESET_%s", timer); reset_timer->name = make_string ("%s_RESET_%s",
fv->name,
timer);
free (reset_timer->distant_name); free (reset_timer->distant_name);
reset_timer->distant_name = make_string (reset_timer->name); reset_timer->distant_name = make_string ("RESET_%s", timer); // irrelevant in PI
reset_timer->rcm = unprotected; reset_timer->rcm = unprotected;
reset_timer->synchronism = synch; reset_timer->synchronism = synch;
APPEND_TO_LIST (Interface, timer_manager->interfaces, reset_timer); APPEND_TO_LIST (Interface, timer_manager->interfaces, reset_timer);
...@@ -252,15 +260,21 @@ void Add_timers_to_function (FV *fv, FV *timer_manager) ...@@ -252,15 +260,21 @@ void Add_timers_to_function (FV *fv, FV *timer_manager)
/* Add corresponding RI in the user FV */ /* Add corresponding RI in the user FV */
reset_timer = Duplicate_Interface (RI, reset_timer, fv); reset_timer = Duplicate_Interface (RI, reset_timer, fv);
free (reset_timer->distant_fv); free (reset_timer->distant_fv);
reset_timer->distant_fv = make_string (timer_manager->name); reset_timer->distant_fv = make_string (timer_manager->name);
reset_timer->name = make_string("RESET_%s", timer);
reset_timer->distant_name = make_string("%s_%s",
fv->name,
reset_timer->name);
APPEND_TO_LIST (Interface, fv->interfaces, reset_timer); APPEND_TO_LIST (Interface, fv->interfaces, reset_timer);
/* Add Unpro PI "SET_timer(value)" in timer manager */ /* Add Unpro PI "SET_timer(value)" in timer manager */
set_timer = Duplicate_Interface (PI, reset_timer, timer_manager); set_timer = Duplicate_Interface (PI, reset_timer, timer_manager);
free (set_timer->name); free (set_timer->name);
set_timer->name = make_string ("SET_%s", timer); set_timer->name = make_string ("%s_SET_%s",
fv->name,
timer);
free (set_timer->distant_name); free (set_timer->distant_name);
set_timer->distant_name = make_string (set_timer->name); set_timer->distant_name = make_string ("SET_%s", timer);
/* Add IN param holding the timer duration */ /* Add IN param holding the timer duration */
Create_Parameter (&param); Create_Parameter (&param);
...@@ -278,6 +292,10 @@ void Add_timers_to_function (FV *fv, FV *timer_manager) ...@@ -278,6 +292,10 @@ void Add_timers_to_function (FV *fv, FV *timer_manager)
/* Add corresponding RI in the user FV */ /* Add corresponding RI in the user FV */
set_timer = Duplicate_Interface (RI, set_timer, fv); set_timer = Duplicate_Interface (RI, set_timer, fv);
free (set_timer->distant_fv); free (set_timer->distant_fv);
set_timer->name = make_string("SET_%s", timer);
set_timer->distant_name = make_string("%s_%s",
fv->name,
set_timer->name);
set_timer->distant_fv = make_string (timer_manager->name); set_timer->distant_fv = make_string (timer_manager->name);
APPEND_TO_LIST (Interface, fv->interfaces, set_timer); APPEND_TO_LIST (Interface, fv->interfaces, set_timer);
}); });
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment