Pull request #218 » codel_rusage.patch
client/c/client.c | ||
---|---|---|
<'
|
||
# 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
|
client/c/init.c | ||
---|---|---|
<'
|
||
# 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
|
client/c/msglib.c | ||
---|---|---|
<'
|
||
# 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
|
client/c/pocolibs-client.c | ||
---|---|---|
/*
|
||
* 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
|
server/control_codels.c | ||
---|---|---|
}
|
||
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");
|
||
... | ... | |
}
|
||
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",
|
server/control_task.c | ||
---|---|---|
<'
|
||
# 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
|
||
... | ... | |
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 --------------------------------------------]"> */
|
||
... | ... | |
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;
|
||
... | ... | |
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);
|
||
... | ... | |
<'}'>
|
||
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 */
|
server/control_task.h | ||
---|---|---|
<'
|
||
# 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
|
||
... | ... | |
#include <assert.h>
|
||
#include <pthread.h>
|
||
#include <stdarg.h>
|
||
#include <sys/time.h>
|
||
#include "csLib.h"
|
||
#include "semLib.h"
|
||
... | ... | |
#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;
|
||
... | ... | |
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 */
|
||
... | ... | |
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);
|
server/exec_codels.c | ||
---|---|---|
}
|
||
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;
|
||
... | ... | |
<' 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;
|
||
... | ... | |
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;
|
||
}
|
server/msglib.c | ||
---|---|---|
<'
|
||
# 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
|