latester can generate histograms + other minor updates
authorMichal Sojka <sojkam1@fel.cvut.cz>
Mon, 29 Nov 2010 15:54:46 +0000 (16:54 +0100)
committerMichal Sojka <sojkam1@fel.cvut.cz>
Mon, 29 Nov 2010 15:54:46 +0000 (16:54 +0100)
latester/latester.c

index 469b794..e32f960 100644 (file)
@@ -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;
 }