Commit 289fe2d1 authored by Maxime Perrotin's avatar Maxime Perrotin
Browse files

Optimize timers in the vertical transformation

Add a filter mechanism that allows to specify which PI actually calls
with RIs. This can save hundreds of AADL ports in large systems.
Applied to timer only but to be extended when information linking PIs to
RIs is available.
parent 4dedd636
Pipeline #365 skipped
......@@ -114,6 +114,10 @@ int Compare_Interface (Interface *one, Interface *two)
return (!strcmp (name1, name2));
}
int Compare_FV (FV *one, FV *two)
{
return (!strcmp(one->name, two->name));
}
int Compare_Protected_Object_Name (Protected_Object_Name *one, Protected_Object_Name *two)
{
......@@ -689,6 +693,7 @@ void Create_Interface(Interface ** i)
(*i)->distant_qgen = distant_qgen;
(*i)->calling_threads = NULL;
(*i)->distant_name = NULL;
(*i)->calling_pis = NULL;
}
// this function clears up an Interface data structure
......@@ -735,16 +740,15 @@ void Clear_Interface(Interface * i)
i->distant_qgen = NULL;
}
if (NULL != i->calling_threads) {
//Clear_FV_List_Keep_Elem(i->calling_threads);
i->calling_threads = NULL;
}
if (NULL != i->distant_name) {
free(i->name);
i->name = NULL;
}
/* Don' t try to free the lists here */
i->calling_threads = NULL;
i->calling_pis = NULL;
}
......
......@@ -174,9 +174,16 @@ void Add_timers_to_function (FV *fv, FV *timer_manager)
{
Interface *expire = NULL, *set_timer = NULL, *reset_timer = NULL;
Parameter *param = NULL;
Interface *cyclic_pi = NULL;
assert (NULL != header && NULL != code);
/* Find the cyclic interface of the timer manager */
FOREACH(pi, Interface, timer_manager->interfaces, {
if (!strcmp(pi->name, "tick_100ms")) cyclic_pi = pi;
});
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",
......@@ -228,6 +235,8 @@ void Add_timers_to_function (FV *fv, FV *timer_manager)
expire->distant_name = make_string (timer);
free (expire->distant_fv);
expire->distant_fv = make_string (fv->name);
/* Filter: set the list of calling PIs in the timer manager */
ADD_TO_SET(Interface, expire->calling_pis, cyclic_pi);
APPEND_TO_LIST (Interface, timer_manager->interfaces, expire);
/* Add Unpro PI "RESET_timer" to timer manager (no param) */
......@@ -423,13 +432,6 @@ void ProcessArtificial_FV_Creation (Interface *i, RCM rcm)
/* Find the corresponding interface in the caller */
distant_RI = FindCorrespondingRI(caller, i);
// FOREACH (interface, Interface, caller->interfaces, {
// if (RI == interface->direction &&
// !strcmp (interface->distant_name, i->name) &&
// !strcmp (interface->distant_fv, i->parent_fv->name)) {
// distant_RI = interface;
// }
// });
if (NULL != distant_RI
&& strcmp(artificial_fv_name, distant_RI->parent_fv->name)) {
......@@ -522,7 +524,7 @@ void Add_RI_To_Thread (Interface *i, FV *fv)
/* Add a thread to the calling list */
int Add_Thread_To_Calling_List (FV_list **calling_threads_list, FV *fv)
void Add_Thread_To_Calling_List (FV_list **calling_threads_list, FV *fv)
{
assert(NULL != calling_threads_list);
assert(NULL != fv);
......@@ -533,9 +535,8 @@ int Add_Thread_To_Calling_List (FV_list **calling_threads_list, FV *fv)
if (NULL != fv) {
APPEND_TO_LIST(FV, *calling_threads_list, fv);
return 0;
return;
}
else return 1;
}
/* Pre-Processing: propagate Calling thread to distant FV
......@@ -544,25 +545,30 @@ void Propagate_Calling_Thread(Interface *i, FV **fv)
{
FV *distant_fv = NULL;
Interface *corresponding_pi = NULL;
distant_fv = (FV *)FindFV (i->distant_fv);
if (NULL != distant_fv) {
/* Find the function to which the RI is connected */
distant_fv = FindFV(i->distant_fv);
if(NULL == distant_fv) {
/* This RI is not connected */
return;
}
/* Find the PI corresponding to the RI passed as first argument */
FOREACH(dist_i, Interface, distant_fv->interfaces, {
//printf("%s %s %s\n", dist_i->name, i->name, i->distant_name);
// Temporary fix to support the new version of tasteIV
char *res=NULL;
// Long-term temporary fix to support the new version of tasteIV
char *res = NULL;
if (NULL != i->distant_name) {
res = strchr(i->distant_name, '.');
if (NULL != res) {
printf("[preprocessing_backend.c] XXX\n");
printf("[preprocessing_backend.c] FIXME\n");
*res = '\0';
}
}
if(PI==dist_i->direction &&
if(PI == dist_i->direction &&
!strcmp(dist_i->name,
NULL != i->distant_name?i->distant_name:i->name)) {
corresponding_pi=dist_i;
NULL != i->distant_name ? i->distant_name : i->name)) {
corresponding_pi = dist_i;
}
});
......@@ -590,7 +596,7 @@ void Propagate_Calling_Thread(Interface *i, FV **fv)
/* And change the "distant fv" field of the corresponding PI */
if(NULL != corresponding_pi->distant_fv) {
free(corresponding_pi->distant_fv);
corresponding_pi->distant_fv=NULL;
corresponding_pi->distant_fv = NULL;
}
build_string(&(corresponding_pi->distant_fv),
(*fv)->name, strlen((*fv)->name));
......@@ -599,10 +605,16 @@ void Propagate_Calling_Thread(Interface *i, FV **fv)
/* Do the same recursively until we reach another thread */
FOREACH(sub_i, Interface, distant_fv->interfaces, {
if (RI == sub_i->direction) {
Propagate_Calling_Thread (sub_i, fv);
/* filter: some RIs are not called by the code of a given PI
* for example the timer expiration signal is only called by the
* cyclic PI of the timer manager. Don't propagate in that case
* to avoid explosion of the number of AADL ports in the CV */
if (NULL == sub_i->calling_pis
|| IN_SET(Interface, sub_i->calling_pis, corresponding_pi)) {
Propagate_Calling_Thread(sub_i, fv);
}
});
}
});
}
}
......@@ -1021,10 +1033,10 @@ void Preprocess_coverage (Process *node)
" exit(0);\n"
"}\n\n");
/* Initialisation code of the coverage manager - nothing special */
/* Initialisation code of the coverage manager */
fprintf (code, "void %s_startup()\n"
"{\n"
" puts(\"use kill -SIGUSR2 to collectcode coverage\");\n"
" puts(\"use kill -SIGUSR2 to collect code coverage\");\n"
" signal(SIGUSR2, gc_handler);\n"
"}\n\n",
fv->name);
......@@ -1088,28 +1100,47 @@ void Preprocessing_Backend (System *s)
FOREACH (fv, FV, s->functions, {
Preprocess_FV(fv);
})
});
/* preprocessing: Propagate calling thread to distant PI (recursively) */
/* Propagate calling thread to distant PI (recursively)
* i.e look for all threads (functions have already been preprocessed)
* then go through all their RIs recursively until reaching another thread,
* and set that the function is a calling thread of the reached one */
FOREACH(fv, FV, s->functions, {
if (thread_runtime == fv->runtime_nature) {
FOREACH(i, Interface, fv->interfaces, {
if (RI == i->direction) Propagate_Calling_Thread (i, &fv);
})
}
})
});
/* Add each RI of passive functions as RI of their calling thread */
/* Add each RI of passive functions as RI of their calling threads */
FOREACH(fv, FV, s->functions, {
if(passive_runtime==fv->runtime_nature) {
FOREACH(i, Interface, fv->interfaces, {
if (RI==i->direction && i->distant_qgen->language == other) {
FOREACH(thread, FV, fv->calling_threads, {
/* Add to calling threads only of PIs that actually call
* the current RI - filtering to be done, but the result
* is the ri->calling_pis list */
FV_list *callers = NULL;
if (NULL == i->calling_pis) {
callers = fv->calling_threads;
}
else {
/* Build a set of actual calling threads of this RI */
FOREACH(calling_pi, Interface, i->calling_pis, {
FOREACH(thread_caller, FV, calling_pi->calling_threads, {
ADD_TO_SET(FV, callers, thread_caller);
});
});
}
//FOREACH(thread, FV, fv->calling_threads, {
FOREACH(thread, FV, callers, {
Add_RI_To_Thread(i, thread);
Propagate_Calling_Thread(i, &thread);
})
});
}
})
});
}
});
......
......@@ -196,6 +196,7 @@ typedef struct t_interface {
char *distant_name;
unsigned long long queue_size;
bool ignore_params;
struct t_Interface_list *calling_pis; // only set in RIs of passive functions
} Interface;
DECLARE_LIST (Interface)
......
......@@ -230,6 +230,7 @@ extern void add_error();
int Compare_Package(Package *one, Package *two);
int Compare_Protected_Object_Name(Protected_Object_Name *one, Protected_Object_Name *two);
int Compare_Interface (Interface *one, Interface *two);
int Compare_FV (FV *one, FV *two);
int Compare_String (String *one, String *two);
int Compare_ASN1_Filename(ASN1_Filename *one, ASN1_Filename *two);
int Compare_ASN1_Module (ASN1_Module *one, ASN1_Module *two);
......@@ -289,6 +290,16 @@ if(Compare_##type(val,elem)) result = 1; \
if (!result) APPEND_TO_LIST(type, list, val);\
}
/* return true if value of type sort is in set */
#define IN_SET(sort, set, val) \
__extension__({\
bool result = false; \
FOREACH(elem, sort, set, {\
if(Compare_##sort(val,elem)) result = true; \
});\
result;\
})
#define FREE_LIST(type, list) \
{\
type##_list *next=NULL;\
......
Markdown is supported
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