From 033225b0b43658326dc10859d1573ceb8d166c16 Mon Sep 17 00:00:00 2001 From: Michal Sojka Date: Mon, 29 Nov 2010 16:54:46 +0100 Subject: [PATCH] latester can generate histograms + other minor updates --- latester/latester.c | 68 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 54 insertions(+), 14 deletions(-) diff --git a/latester/latester.c b/latester/latester.c index 469b794..e32f960 100644 --- a/latester/latester.c +++ b/latester/latester.c @@ -56,6 +56,8 @@ struct options { unsigned timeout_ms; unsigned count; unsigned oneattime; + char *file; + char *histogram_fn; } opt = { .id = 10, .period_us = 0, @@ -77,6 +79,8 @@ struct msg_info { struct msg_info msg_infos[MAX_INFOS]; uint16_t curr_msg = 0; +struct histogram histogram; + static inline struct msg_info *frame2info(struct can_frame *frame) { uint16_t idx; @@ -156,6 +160,13 @@ void dbg_print_timespec(char *msg, struct timespec *tv) printf("%s sec=%ld nsec=%ld\n", msg, tv->tv_sec, tv->tv_nsec); } +static inline unsigned get_msg_latency_us(struct msg_info *mi) +{ + struct timespec diff; + timespec_subtract(&diff, &mi->ts_rx_final_kern, &mi->ts_rx_onwire_kern); + return diff.tv_sec * 1000000 + diff.tv_nsec/1000; +} + void set_sched_policy_and_prio(int policy, int rtprio) { struct sched_param scheduling_parameters; @@ -302,7 +313,11 @@ void process_final_rx(int s) mi->ts_rx_final_kern = ts_kern; mi->ts_rx_final = ts_user; - print_msg_info(mi); + if (opt.histogram_fn) + histogram_add(&histogram, get_msg_latency_us(mi)); + + if (!opt.file) + print_msg_info(mi); } void *measure_thread(void *arg) @@ -348,7 +363,7 @@ void *measure_thread(void *arg) pfd[i].fd = s; if (i == 0) - pfd[i].events = POLLIN | POLLERR | (opt.period_us == 0 ? POLLOUT : 0); + pfd[i].events = POLLIN | POLLERR | ((opt.period_us == 0 && !opt.oneattime) ? POLLOUT : 0); else pfd[i].events = POLLIN; } @@ -356,17 +371,26 @@ void *measure_thread(void *arg) set_sched_policy_and_prio(SCHED_FIFO, 99); #define SEND() \ - do { \ + do { printf("send\n"); \ ret = send_frame(pfd[0].fd); \ if (ret != sizeof(struct can_frame)) \ error(1, errno, "send_frame"); \ msg_in_progress++; \ } while (0) + if (opt.oneattime) { + SEND(); + count = 1; + } + while (!finish_flag && (opt.count == 0 || count < opt.count || msg_in_progress != 0)) { + get_next_timeout(&timeout); + printf("ppoll"); + fflush(stdout); ret = ppoll(pfd, num_interfaces, &timeout, NULL); + printf("=%d\n", ret); switch (ret) { case -1: // Error if (!INTERRUPTED_SYSCALL(errno)) @@ -386,10 +410,8 @@ void *measure_thread(void *arg) process_tx(pfd[0].fd); } if (pfd[0].revents & POLLOUT) { - if ((opt.count == 0 || count++ < opt.count) && - !opt.oneattime) { + if (opt.count == 0 || count++ < opt.count) SEND(); - } } pfd[0].revents = 0; @@ -421,10 +443,12 @@ struct poptOption optionsTable[] = { { "device", 'd', POPT_ARG_ARGV, &opt.interface, 'd', "Interface to use. Must be given two times (tx, rx) or three times (tx, rx1, rx2)", "interface" }, { "count", 'c', POPT_ARG_INT|POPT_ARGFLAG_SHOW_DEFAULT, &opt.count, 0, "The count of messages to send, zero corresponds to infinity", "num"}, { "id", 'i', POPT_ARG_INT|POPT_ARGFLAG_SHOW_DEFAULT, &opt.id, 0, "CAN ID of sent messages", "id"}, - { "period", 'p', POPT_ARG_INT|POPT_ARGFLAG_SHOW_DEFAULT, &opt.period_us, 0, "Period for sending messages or zero (default) to send as fast as possible", "us"}, - { "timeout",'t', POPT_ARG_INT|POPT_ARGFLAG_SHOW_DEFAULT, &opt.timeout_ms,0, "Timeout when period is zero", "ms"}, - { "oneattime",'o', POPT_ARG_NONE, &opt.oneattime,0, "Send the next message only when the previous was finally received"}, - { "verbose",'v', POPT_ARG_NONE, NULL, 'v', "Send the next message only when the previous was finally received"}, + { "period", 'p', POPT_ARG_INT|POPT_ARGFLAG_SHOW_DEFAULT, &opt.period_us, 0, "Period for sending messages or zero (default) to send as fast as possible", "us"}, + { "timeout",'t', POPT_ARG_INT|POPT_ARGFLAG_SHOW_DEFAULT, &opt.timeout_ms,0, "Timeout when period is zero", "ms"}, + { "oneattime",'o', POPT_ARG_NONE, &opt.oneattime,0, "Send the next message only when the previous was finally received"}, + { "verbose",'v', POPT_ARG_NONE, NULL, 'v', "Send the next message only when the previous was finally received"}, + { "file", 'f', POPT_ARG_STRING, &opt.file, 0, "File where to store results", "filename"}, + { "histogram", 'h', POPT_ARG_STRING, &opt.histogram_fn, 0, "Store histogram in file", "filename"}, POPT_AUTOHELP { NULL, 0, 0, NULL, 0 } }; @@ -453,6 +477,9 @@ int parse_options(int argc, const char *argv[]) if (num_interfaces < 2 || num_interfaces > 3) error(1, 0, "-d option must be given exactly 2 or 3 times"); + if (opt.oneattime && opt.period_us) + error(1, 0, "oneattime and period cannot be specified at the same time"); + poptFreeContext(optCon); return 0; @@ -464,7 +491,8 @@ int main(int argc, const char *argv[]) pthread_t thread; sigset_t set; int ret; - + FILE *fhist; + parse_options(argc, argv); mlockall(MCL_CURRENT | MCL_FUTURE); @@ -472,14 +500,26 @@ int main(int argc, const char *argv[]) signal(SIGINT, term_handler); signal(SIGTERM, term_handler); + if (opt.histogram_fn) { + histogram_init(&histogram, 1000000, 5); + fhist = fopen(opt.histogram_fn, "w"); + if (fhist == NULL) + error(1, errno, "open %s", opt.histogram_fn); + } + pthread_create(&thread, 0, measure_thread, NULL); - while (!finish_flag) { - sleep(1); - } +/* while (!finish_flag) { */ +/* sleep(1); */ +/* } */ pthread_join(thread, NULL); + if (opt.histogram_fn) { + histogram_fprint(&histogram, fhist); + fclose(fhist); + } + return 0; } -- 2.39.2