Commit 73dcea14 authored by Tristan Gingold's avatar Tristan Gingold

wrtd: compute latency

parent 4a86a4f6
......@@ -201,6 +201,7 @@ static void wrtd_route(struct wrtd_rule *rule, const struct wrtd_event *ev)
{
struct wrtd_event tev;
struct wrtd_tstamp now;
uint32_t lat_ns;
/* Event was received. */
rule->stat.rx_events++;
......@@ -224,7 +225,30 @@ static void wrtd_route(struct wrtd_rule *rule, const struct wrtd_event *ev)
ts_now(&now);
/* TODO: period and latency. */
/* Compute latency. */
do {
lat_ns = now.ns - ev->ts.ns;
if(lat_ns >> 31) {
/* Result is negatif, possible only if differ by
1 sec. */
if (ev->ts.seconds + 1 == now.seconds)
lat_ns += 1000000000;
else
break;
}
else if (ev->ts.seconds != now.seconds) {
/* In the future or way in the past. */
break;
}
if (lat_ns > rule->stat.lat_max_ns)
rule->stat.lat_max_ns = lat_ns;
rule->stat.lat_lo_ns += lat_ns;
if (rule->stat.lat_lo_ns < lat_ns)
rule->stat.lat_hi_ns++;
rule->stat.lat_nbr++;
}
while (0);
/* Delay. */
if (rule->conf.delay_ns)
......
......@@ -92,6 +92,11 @@ struct wrtd_rule_stats {
uint32_t tx_events;
struct wrtd_tstamp tx_last;
uint32_t lat_max_ns;
uint32_t lat_lo_ns;
uint32_t lat_hi_ns;
uint32_t lat_nbr;
uint32_t miss_holdoff;
uint32_t miss_late;
struct wrtd_tstamp miss_last;
......
......@@ -262,6 +262,42 @@ enum wrtd_status wrtd_attr_set_rule_destination(struct wrtd_dev *wrtd,
return WRTD_SUCCESS;
}
enum wrtd_status wrtd_attr_get_rule_destination(struct wrtd_dev *wrtd,
const char *rep_cap_id,
int32_t buf_size,
char *dst)
{
enum wrtd_status status;
unsigned int idx;
status = wrtd_find_rule(wrtd, rep_cap_id, &idx);
WRTD_RETURN_IF_ERROR(status);
status = wrtd_id_copy_buf(wrtd, dst, buf_size,
wrtd->rules[idx].rule.conf.dest_id);
WRTD_RETURN_IF_ERROR(status);
return WRTD_SUCCESS;
}
enum wrtd_status wrtd_attr_get_rule_source(struct wrtd_dev *wrtd,
const char *rep_cap_id,
int32_t buf_size,
char *dst)
{
enum wrtd_status status;
unsigned int idx;
status = wrtd_find_rule(wrtd, rep_cap_id, &idx);
WRTD_RETURN_IF_ERROR(status);
status = wrtd_id_copy_buf(wrtd, dst, buf_size,
wrtd->rules[idx].rule.conf.source_id);
WRTD_RETURN_IF_ERROR(status);
return WRTD_SUCCESS;
}
enum wrtd_status wrtd_attr_set_rule_delay(struct wrtd_dev *wrtd,
const char *rep_cap_id,
const struct wrtd_tstamp *value)
......@@ -492,6 +528,31 @@ enum wrtd_status wrtd_set_attr_string(struct wrtd_dev *wrtd,
default:
return wrtd_return_error
(wrtd, WRTD_ERROR_INVALID_ATTRIBUTE,
"string attribute %u is not known", id);
"string set attribute %u is not known", id);
}
}
enum wrtd_status wrtd_get_attr_string(struct wrtd_dev *wrtd,
const char *rep_cap_id,
enum wrtd_attr id,
int32_t value_buf_size,
char *value)
{
enum wrtd_status status;
status = wrtd_validate_id(wrtd, rep_cap_id);
WRTD_RETURN_IF_ERROR(status);
switch(id) {
case WRTD_ATTR_RULE_SOURCE:
return wrtd_attr_get_rule_source
(wrtd, rep_cap_id, value_buf_size, value);
case WRTD_ATTR_RULE_DESTINATION:
return wrtd_attr_get_rule_destination
(wrtd, rep_cap_id, value_buf_size, value);
default:
return wrtd_return_error
(wrtd, WRTD_ERROR_INVALID_ATTRIBUTE,
"string get attribute %u is not known", id);
}
}
......@@ -595,6 +595,20 @@ enum wrtd_status wrtd_remove_alarm(struct wrtd_dev *wrtd,
return WRTD_SUCCESS;
}
enum wrtd_status wrtd_id_copy_buf(struct wrtd_dev *wrtd,
char *dst, int32_t buf_size, const char *id)
{
if(buf_size < WRTD_ID_LEN)
return wrtd_return_error(wrtd, WRTD_ERROR_BUFFER_TOO_SHORT,
"buffer to short for an id");
memset(dst, 0, WRTD_ID_LEN);
wrtd_id_copy(dst, id);
if(buf_size > WRTD_ID_LEN)
dst[WRTD_ID_LEN] = 0;
return WRTD_SUCCESS;
}
enum wrtd_status wrtd_get_alarm_id(struct wrtd_dev *wrtd,
int32_t index,
int32_t name_buffer_size,
......@@ -604,10 +618,6 @@ enum wrtd_status wrtd_get_alarm_id(struct wrtd_dev *wrtd,
unsigned i;
unsigned n;
if (name_buffer_size < WRTD_ID_LEN)
return wrtd_return_error(wrtd, WRTD_ERROR_BUFFER_TOO_SHORT,
"buffer is too small");
/* Load all alarms. */
status = wrtd_fill_alarms(wrtd);
WRTD_RETURN_IF_ERROR(status);
......@@ -618,9 +628,9 @@ enum wrtd_status wrtd_get_alarm_id(struct wrtd_dev *wrtd,
if (wrtd_id_null(aid))
continue;
if (n == index) {
wrtd_id_copy(rep_cap_id, aid);
if (name_buffer_size > WRTD_ID_LEN)
rep_cap_id[WRTD_ID_LEN] = 0;
status = wrtd_id_copy_buf
(wrtd, rep_cap_id, name_buffer_size, aid);
WRTD_RETURN_IF_ERROR(status);
return WRTD_SUCCESS;
}
n++;
......@@ -847,10 +857,6 @@ enum wrtd_status wrtd_get_rule_id(struct wrtd_dev *wrtd,
unsigned i;
unsigned n;
if (name_buffer_size < WRTD_ID_LEN)
return wrtd_return_error(wrtd, WRTD_ERROR_BUFFER_TOO_SHORT,
"buffer is too small");
/* Load all rules. */
status = wrtd_fill_rules(wrtd);
WRTD_RETURN_IF_ERROR(status);
......@@ -861,9 +867,9 @@ enum wrtd_status wrtd_get_rule_id(struct wrtd_dev *wrtd,
if (wrtd_id_null(aid))
continue;
if (n == index) {
wrtd_id_copy(rep_cap_id, aid);
if (name_buffer_size > WRTD_ID_LEN)
rep_cap_id[WRTD_ID_LEN] = 0;
status = wrtd_id_copy_buf
(wrtd, rep_cap_id, name_buffer_size, aid);
WRTD_RETURN_IF_ERROR(status);
return WRTD_SUCCESS;
}
n++;
......
......@@ -205,4 +205,8 @@ static inline void wrtd_id_copy(char *dst, const char *src)
strncpy(dst, src, WRTD_ID_LEN);
}
/* Copy ID to DST of length BUF_SIZE. Check length, pad with null. */
enum wrtd_status wrtd_id_copy_buf(struct wrtd_dev *wrtd,
char *dst, int32_t buf_size, const char *id);
#endif /* __LIBWRTD_PRIVATE__H__ */
......@@ -142,6 +142,7 @@ static void disp_rule_conf(const struct wrtd_rule *rule, unsigned nbr_rules)
static void disp_rule_stat(const struct wrtd_rule *rule)
{
const struct wrtd_rule_stats *s = &rule->stat;
uint64_t lat_ns;
printf(" rx_events: %u\n", s->rx_events);
printf(" rx_last: ");
print_ts(&s->rx_last);
......@@ -150,7 +151,14 @@ static void disp_rule_stat(const struct wrtd_rule *rule)
printf(" tx_last: ");
print_ts(&s->tx_last);
printf("\n"
" miss_holdoff: %u\n", s->miss_holdoff);
" lat_max: %uns\n", s->lat_max_ns);
lat_ns = s->lat_lo_ns + ((uint64_t)s->lat_hi_ns << 32);
printf(" latency: %"PRIu64"ns/%u = ", lat_ns, s->lat_nbr);
if (s->lat_nbr == 0)
printf("NA\n");
else
printf("%uns\n", (uint32_t)(lat_ns / s->lat_nbr));
printf(" miss_holdoff: %u\n", s->miss_holdoff);
printf(" miss_late: %u\n", s->miss_late);
printf(" miss_last: ");
print_ts(&s->miss_last);
......@@ -696,7 +704,6 @@ static enum wrtd_status wrtd_cmd_list_rules(struct wrtd_dev *wrtd,
{
enum wrtd_status status;
int32_t count;
char id[WRTD_ID_LEN];
int32_t i;
status = wrtd_get_attr_int32 (wrtd, WRTD_GLOBAL_REP_CAP_ID,
......@@ -706,16 +713,28 @@ static enum wrtd_status wrtd_cmd_list_rules(struct wrtd_dev *wrtd,
printf ("%d rules:\n", count);
for (i = 0; i < count; i++) {
bool enabled;
char rid[WRTD_ID_LEN + 1];
char id[WRTD_ID_LEN + 1];
status = wrtd_get_rule_id(wrtd, i, sizeof(id), id);
status = wrtd_get_rule_id(wrtd, i, sizeof(rid), rid);
WRTD_RETURN_IF_ERROR(status);
printf(" %.*s", WRTD_ID_LEN, id);
printf(" %s", rid);
status = wrtd_get_attr_bool(wrtd, id, WRTD_ATTR_RULE_ENABLED,
status = wrtd_get_attr_bool(wrtd, rid, WRTD_ATTR_RULE_ENABLED,
&enabled);
WRTD_RETURN_IF_ERROR(status);
printf(" %s\n", enabled ? "enabled" : "disabled");
printf(" %s", enabled ? "enabled" : "disabled");
status = wrtd_get_attr_string
(wrtd, rid, WRTD_ATTR_RULE_SOURCE, sizeof(id), id);
WRTD_RETURN_IF_ERROR(status);
printf(" %s", id);
status = wrtd_get_attr_string
(wrtd, rid, WRTD_ATTR_RULE_DESTINATION, sizeof(id), id);
WRTD_RETURN_IF_ERROR(status);
printf(" -> %s\n", id);
}
return WRTD_SUCCESS;
}
......
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