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)
fprintf(b, "%s", qgen_args);
fprintf(b, ");\n\n");
} else {
}
else {
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)
* 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"
*/
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
(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, (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);
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);
/*
* 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 retrieve the caller thread ID using the "stack"
*/
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
(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, (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);
fprintf(b,
"\t\t\tValue.OUTPORT_%s_DATA.Buffer (J) := PolyORB_HI_Generated.Types.Stream_Element%s\n",
i->name,
get_context()->aadlv2?"_Buffer":"");
fprintf(b,
"\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;
}
"\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,
"\t\t\tValue.OUTPORT_%s_DATA.Buffer (J) := PolyORB_HI_Generated.Types.Stream_Element%s\n",
i->name,
get_context()->aadlv2?"_Buffer":"");
fprintf(b,
"\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) {
fprintf(b, "\t\tPut_Value (%s_%s_K, Value);\n",
i->parent_fv->process->identifier,
i->parent_fv->name);
if (1 == count) {
fprintf(b, "\t\t%s_async_ri_wrappers.vm_%s_vt",
calltmp->value->name,
i->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);
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 { // 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");
else {
/* Build the list of calling threads for this RI */
FV_list *calltmp = NULL;
if (NULL == i->calling_pis) calltmp = i->parent_fv->calling_threads;
......@@ -585,49 +640,6 @@ void add_RI_to_ada_wrappers(Interface * i)
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");
if (protected == i->rcm) {
......@@ -638,13 +650,13 @@ void add_RI_to_ada_wrappers(Interface * i)
}
if (passive_runtime == i->parent_fv->runtime_nature) {
if (cnt > 1) {
if (count > 1) {
fprintf(b, "callinglist.get_top_value");
}
else if (1 == cnt) {
fprintf(b, "%d", i->parent_fv->calling_threads->value->thread_id);
else if (1 == count) {
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 ("** 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");
......
......@@ -538,13 +538,28 @@ void add_RI_to_c_wrappers(Interface * i)
}
}
else { /* synch==i->synchronism (RI is synchronous) :
make a direct call to the remote function
defined in remote polyorb_interface.c,
else { /* synch==i->synchronism (RI is synchronous) :
make a direct call to the remote function
defined in remote polyorb_interface.c,
and pass the thread id as parameter */
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,
NULL != i->distant_name ? i->distant_name : i->name);
......@@ -554,8 +569,7 @@ void add_RI_to_c_wrappers(Interface * i)
fprintf(b, "%s_callinglist_get_top_value()",
i->parent_fv->name);
} 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 == count) {
printf
("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)
FOREACH (timer, String, fv->timer_list, {
/* Declare functions in timer manager code */
fprintf (header, "void %s_PI_SET_%s(const asn1SccT_UInt32 *val);\n\n",
timer_manager->name, timer);
fprintf (code, "void %s_PI_SET_%s(const asn1SccT_UInt32 *val)\n"
fprintf (header, "void %s_PI_%s_SET_%s(const asn1SccT_UInt32 *val);\n\n",
timer_manager->name,
fv->name,
timer);
fprintf (code, "void %s_PI_%s_SET_%s(const asn1SccT_UInt32 *val)\n"
"{\n"
" /* Timer value must be multiple of 100 ms */\n"
" assert (*val %% 100 == 0);\n"
......@@ -196,18 +198,22 @@ void Add_timers_to_function (FV *fv, FV *timer_manager)
" timers[%s_%s].value = *val / 100;\n"
"}\n\n",
timer_manager->name,
fv->name,
timer,
fv->name,
timer,
fv->name,
timer);
fprintf (header, "void %s_PI_RESET_%s();\n\n",
timer_manager->name, timer);
fprintf (code, "void %s_PI_RESET_%s()\n"
fprintf (header, "void %s_PI_%s_RESET_%s();\n\n",
timer_manager->name,
fv->name,
timer);
fprintf (code, "void %s_PI_%s_RESET_%s()\n"
"{\n"
" timers[%s_%s].state = inactive;\n"
"}\n\n",
timer_manager->name,
fv->name,
timer,
fv->name,
timer);
......@@ -242,9 +248,11 @@ void Add_timers_to_function (FV *fv, FV *timer_manager)
/* Add Unpro PI "RESET_timer" to timer manager (no param) */
reset_timer = Duplicate_Interface (PI, expire, timer_manager);
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);
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->synchronism = synch;
APPEND_TO_LIST (Interface, timer_manager->interfaces, reset_timer);
......@@ -252,15 +260,21 @@ void Add_timers_to_function (FV *fv, FV *timer_manager)
/* Add corresponding RI in the user FV */
reset_timer = Duplicate_Interface (RI, reset_timer, 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);
/* Add Unpro PI "SET_timer(value)" in timer manager */
set_timer = Duplicate_Interface (PI, reset_timer, timer_manager);
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);
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 */
Create_Parameter (&param);
......@@ -278,6 +292,10 @@ void Add_timers_to_function (FV *fv, FV *timer_manager)
/* Add corresponding RI in the user FV */
set_timer = Duplicate_Interface (RI, set_timer, 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);
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