diff --git a/client/c/client.c b/client/c/client.c index ec394db..db2ce4a 100644 --- a/client/c/client.c +++ b/client/c/client.c @@ -1,5 +1,5 @@ <' -# Copyright (c) 2012-2014,2017-2019 LAAS/CNRS +# Copyright (c) 2012-2019 LAAS/CNRS # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/client/c/init.c b/client/c/init.c index 625ea96..80e2eda 100644 --- a/client/c/init.c +++ b/client/c/init.c @@ -1,5 +1,5 @@ <' -# Copyright (c) 2012-2017,2019 LAAS/CNRS +# Copyright (c) 2012-2019 LAAS/CNRS # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/client/c/msglib.c b/client/c/msglib.c index 567b7f0..9c2d13a 100644 --- a/client/c/msglib.c +++ b/client/c/msglib.c @@ -1,5 +1,5 @@ <' -# Copyright (c) 2012-2013,2017-2018 LAAS/CNRS +# Copyright (c) 2012-2019 LAAS/CNRS # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/client/c/pocolibs-client.c b/client/c/pocolibs-client.c index b1008b3..4fbe0b4 100644 --- a/client/c/pocolibs-client.c +++ b/client/c/pocolibs-client.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2014,2016-2019 LAAS/CNRS + * Copyright (c) 2012-2019 LAAS/CNRS * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/server/control_codels.c b/server/control_codels.c index 971bcc5..e8876a9 100644 --- a/server/control_codels.c +++ b/server/control_codels.c @@ -232,7 +232,7 @@ genom_<"$comp">_<"[$s name]">_controlcb( } lappend plist &self->control.context '> - s = <"[$validate invoke $plist]">; + call_codel_with_timelog(<"[$validate name]">_ru, s = <"[$validate invoke $plist]">); genom_give_resource(self, self->resources.control = NULL); genom_log_debug("service <"[$s name]"> validation returned %s", s?s:"ok"); @@ -306,7 +306,7 @@ genom_<"$comp">_<"[$s name]">_controlcb( } lappend plist &self->control.context '> - s = <"[$c invoke $plist]">; + call_codel_with_timelog(<"[$c name]">_ru, s = <"[$c invoke $plist]">); genom_give_resource(self, self->resources.control = NULL); genom_log_debug("service %s codel %s returned %s", diff --git a/server/control_task.c b/server/control_task.c index 9e20096..0fc0e06 100644 --- a/server/control_task.c +++ b/server/control_task.c @@ -1,5 +1,5 @@ <' -# Copyright (c) 2011-2017,2019 LAAS/CNRS +# Copyright (c) 2011-2019 LAAS/CNRS # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -56,7 +56,8 @@ struct CS_SERV_IDS { static void <"$comp">_<"[$s name]">_rqstcb(SERV_ID csserv, int sid); <'}'> static void * <"$comp">_cntrl_task(void *); - +static void report_codels_usage(struct codel_usage usage[]); +static void report_nb_transitions(unsigned int nb_call[]); /* <"[--- genom_${comp}_init --------------------------------------------]"> */ @@ -156,6 +157,22 @@ genom_<"$comp">_init(void) pthread_mutex_init(&self->resources.lock, NULL); pthread_cond_init(&self->resources.sync, NULL); + /* Initialise codels rusage struct and transition table*/ + { + int i; + for(i = 0; i < ncodel_max; i++) { + self->codels_usage[i].calls = 0; + self->codels_usage[i].min = 9999.; + self->codels_usage[i].max = 0.; + self->codels_usage[i].cum = 0.; + } + + for(i = 0; i < n_trans_max; i++) { + self->nb_trans_called[i] = 0; + } + + } + /* create posters */ if (genom_metadata_<"$comp">_init(self)) goto error; if (genom_state_<"$comp">_init(self)) goto error; @@ -331,6 +348,9 @@ genom_<"$comp">_fini(void *data) pthread_mutex_unlock(&self->control.lock); } + report_codels_usage(self->codels_usage); + report_nb_transitions(self->nb_trans_called); + /* clean up */ <'foreach p [$component ports] {'> genom_<"$comp">_<"[$p name]">_delete(&self->control.context); @@ -628,4 +648,130 @@ clean: <'}'> +void report_nb_transitions(unsigned int nb_call[]) +{ +<'set tasks [$component tasks]'> +<'foreach task $tasks {'> +<'foreach obj [list $task {*}[$task services]] {'> +<' foreach state [$obj fsm] {'> +<' foreach y [[$obj fsm $state] yield] {'> + if (nb_call[<"[$obj name]">_<"[$state cname]">_<"[$y cname]">_st]) + genom_log_info("%u transitions for %s, from %s to %s.", + nb_call[<"[$obj name]">_<"[$state cname]">_<"[$y cname]">_st], + "<"[$obj name]">", "<"[$state cname]">", "<"[$y cname]">"); +<' }'> +<' }'> +<'}'> +<'}'> +} + + +void report_codel_usage(char *name, struct codel_usage cu) +{ + if (cu.calls) { + genom_log_info("%s called: %lu times, min: %f, max: %f, avg: %f.", name, cu.calls, cu.min, cu.max, cu.cum/cu.calls); + } else { + genom_log_info("%s not called once.", name); + } +} + +void report_codels_usage(struct codel_usage usage[]) { +<' +set tasks [$component tasks] +lappend tasks "" +foreach task $tasks { +if {$task ne ""} {'> +<' foreach codel [$task codels] {'> +<' if {![catch {dict get $gcodels_for_report [$codel name]} prev]} { + continue + } + dict set gcodels_for_report [$codel name] "task [$task name]" +'> + report_codel_usage("<"[$codel name]">",usage[<"[$codel name]">_ru]); +<' } '> +<'} + +if {$task eq ""} { + foreach service [$component services] { + if {[llength [$service validate]] == 0} continue'> +<' foreach codel [$service validate] {'> +<' + if {![catch {dict get $gcodels_for_report [$codel name]} prev]} { + continue + } + dict set gcodels_for_report [$codel name] "service [$service name] validation" +'> + report_codel_usage("<"[$codel name]">",usage[<"[$codel name]">_ru]); +<' } '> +<' } '> +<'} + +foreach service [$component services] { + if {[catch {$service task} t]} { set t "" } + if {$t != $task || [llength [$service codels]] == 0} { + continue + } '> +<' foreach codel [$service codels] {'> +<' + if {![catch {dict get $gcodels_for_report [$codel name]} prev]} { + puts "\n/* already defined in $prev */" + continue + } + dict set gcodels_for_report [$codel name] "service [$service name]" +'> + report_codel_usage("<"[$codel name]">",usage[<"[$codel name]">_ru]); +<' } '> +<' } '> +<'}'> + printf("********* The wcet of the <"$comp"> codels are ***************\n"); +<'foreach task $tasks { +if {$task ne ""} {'> +<' foreach codel [$task codels] {'> +<' if {![catch {dict get $gcodels_for_wcet [$codel name]} prev]} { + continue + } + dict set gcodels_for_wcet [$codel name] "task [$task name]" +'> + if (usage[<"[$codel name]">_ru].calls) + printf("<"$comp">_<"[$codel name]"> %f\n", usage[<"[$codel name]">_ru].max); +<' } '> +<'} + +if {$task eq ""} { + foreach service [$component services] { + if {[llength [$service validate]] == 0} continue'> +<' foreach codel [$service validate] {'> +<' + if {![catch {dict get $gcodels_for_wcet [$codel name]} prev]} { + continue + } + dict set gcodels_for_wcet [$codel name] "service [$service name] validation" +'> + if (usage[<"[$codel name]">_ru].calls) + printf("<"$comp">_<"[$codel name]"> %f\n", usage[<"[$codel name]">_ru].max); +<' } '> +<' } '> +<'} + +foreach service [$component services] { + if {[catch {$service task} t]} { set t "" } + if {$t != $task || [llength [$service codels]] == 0} { + continue + } '> +<' foreach codel [$service codels] {'> +<' + if {![catch {dict get $gcodels_for_wcet [$codel name]} prev]} { + puts "\n/* already defined in $prev */" + continue + } + dict set gcodels_for_wcet [$codel name] "service [$service name]" +'> + if (usage[<"[$codel name]">_ru].calls) + printf("<"$comp">_<"[$codel name]"> %f\n", usage[<"[$codel name]">_ru].max); +<' } '> +<' } '> +<'} '> + printf("*****************************************************\n"); +} + /* eof */ diff --git a/server/control_task.h b/server/control_task.h index 07416ee..01b3100 100644 --- a/server/control_task.h +++ b/server/control_task.h @@ -1,5 +1,5 @@ <' -# Copyright (c) 2011-2015,2017 LAAS/CNRS +# Copyright (c) 2011-2019 LAAS/CNRS # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -30,6 +30,7 @@ lang c #include #include #include +#include #include "csLib.h" #include "semLib.h" @@ -43,6 +44,82 @@ lang c #include "<"$comp">_activity.h" +/* --- an enum of all the codels defined ----------------------------------------------------- */ + +struct codel_usage { + char *name; + unsigned long calls; + float max; + float min; + float cum; +}; + +enum { +<' +set tasks [$component tasks] +lappend tasks "" +foreach task $tasks { +if {$task ne ""} {'> +<' foreach codel [$task codels] {'> +<' if {![catch {dict get $generated_codels [$codel name]} prev]} { + continue + } + dict set generated_codels [$codel name] "task [$task name]" +'> + <"[$codel name]">_ru, +<' } '> +<'} + +if {$task eq ""} { + foreach service [$component services] { + if {[llength [$service validate]] == 0} continue'> +<' foreach codel [$service validate] {'> +<' + if {![catch {dict get $generated_codels [$codel name]} prev]} { + continue + } + dict set generated_codels [$codel name] "service [$service name] validation" +'> + <"[$codel name]">_ru, +<' } '> +<' } '> +<'} + +foreach service [$component services] { + if {[catch {$service task} t]} { set t "" } + if {$t != $task || [llength [$service codels]] == 0} { + continue + } '> +<' foreach codel [$service codels] {'> +<' + if {![catch {dict get $generated_codels [$codel name]} prev]} { + continue + } + dict set generated_codels [$codel name] "service [$service name]" +'> + <"[$codel name]">_ru, +<' } '> +<' } '> +<'} '> + ncodel_max +}; + +/* --- an enum of all the state transition possible------------------------------------------------ */ + +enum { +<'set tasks [$component tasks]'> +<'foreach task $tasks {'> +<'foreach obj [list $task {*}[$task services]] {'> +<' foreach state [$obj fsm] {'> +<' foreach y [[$obj fsm $state] yield] {'> + <"[$obj name]">_<"[$state cname]">_<"[$y cname]">_st, +<' }'> +<' }'> +<'}'> +<'}'> + n_trans_max +}; + /* --- internal state ------------------------------------------------------ */ extern const char *genom_instance; @@ -124,6 +201,10 @@ struct genom_component_data { pthread_mutex_t lock; pthread_cond_t sync; } resources; + + struct codel_usage codels_usage[ncodel_max]; + unsigned int nb_trans_called[n_trans_max]; + }; /* resource access */ @@ -146,6 +227,20 @@ struct genom_component_data { pthread_mutex_unlock(&self->resources.lock); \ } while(0) +#define call_codel_with_timelog(codel,call) do{ \ + float last; \ + struct timeval tvs, tve; \ + struct codel_usage *usage = &(self->codels_usage[codel]); \ + gettimeofday(&tvs, NULL); \ + call; \ + gettimeofday(&tve, NULL); \ + usage->calls++; \ + last = tve.tv_sec - tvs.tv_sec + \ + (tve.tv_usec - tvs.tv_usec)*1e-6; \ + if (last > usage->max) usage->max = last; \ + if (last < usage->min) usage->min = last; \ + usage->cum += last; \ + } while (0) /* control task */ void * genom_<"$comp">_init(void); diff --git a/server/exec_codels.c b/server/exec_codels.c index 5544263..af03e23 100644 --- a/server/exec_codels.c +++ b/server/exec_codels.c @@ -100,7 +100,7 @@ static __inline__ genom_event } lappend plist "&self->tasks.[$task name].context" '> - s = <"[$codel invoke $plist]">; + call_codel_with_timelog(<"[$codel name]">_ru, s = <"[$codel invoke $plist]">); genom_give_resource(self, self->resources.task_<"[$task name]"> = NULL); return s; @@ -126,19 +126,22 @@ static __inline__ enum genom_activity_status <' foreach y [[$obj fsm $state] yield] {'> <' if {"pause" in [$y kind]} continue'> <' if {"ether" eq [$y name]} continue'> - s == <"[$y cname]"> || + (s == <"[$y cname]"> && + ++(self->nb_trans_called[<"[$obj name]">_<"[$state cname]">_<"[$y cname]">_st])) || <' }'> - 0) { - a->state = s; + 0) { + a->state = s; return ACT_RUN; } if ( <' foreach y [[$obj fsm $state] yield] {'> <' if {"pause" in [$y kind]} { '> - (s == <"[$y cname]"> && (s = <"$comp">_<"[$y name]">)) || + (s == <"[$y cname]"> && + ++(self->nb_trans_called[<"[$obj name]">_<"[$state cname]">_<"[$y cname]">_st]) && + (s = <"$comp">_<"[$y name]">)) || <' }'> <' }'> - 0) { + 0) { a->state = s; a->pause = 1; return ACT_RUN; @@ -146,10 +149,11 @@ static __inline__ enum genom_activity_status if ( <' foreach y [[$obj fsm $state] yield] {'> <' if {"ether" eq [$y name]} {'> - s == <"[$y cname]"> || + (s == <"[$y cname]"> && + ++(self->nb_trans_called[<"[$obj name]">_<"[$state cname]">_<"[$y cname]">_st])) || <' }'> <' }'> - 0) { + 0) { a->state = <"$comp">_ether; return ACT_ETHER; } diff --git a/server/msglib.c b/server/msglib.c index 9742680..c44a48a 100644 --- a/server/msglib.c +++ b/server/msglib.c @@ -1,5 +1,5 @@ <' -# Copyright (c) 2011-2013,2017-2018 LAAS/CNRS +# Copyright (c) 2011-2019 LAAS/CNRS # All rights reserved. # # Redistribution and use in source and binary forms, with or without