]> rtime.felk.cvut.cz Git - can-benchmark.git/blobdiff - latester/latester.c
Increase txqueue length (qdisc) to avoid ENOBUFS errors
[can-benchmark.git] / latester / latester.c
index d178e1eb907f990b43b331ce86d06ab2fd88b0e2..a72558a06b5fe8de6c0a1422bd7f6538486c0e21 100644 (file)
@@ -74,10 +74,12 @@ struct options opt = {
 
 struct {
        unsigned enobufs;
+       unsigned overrun;
 } stats;
 
 int num_interfaces = 0;
 int count = 0;                 /* Number of sent messages */
+unsigned msg_in_progress = 0;
 int completion_pipe[2];
 
 struct msg_info {
@@ -130,7 +132,7 @@ static inline struct msg_info *frame2info(struct can_frame *frame)
                if (idx >= MAX_INFOS)
                        error(1, 0, "%s idx too high", __FUNCTION__);
        } else {
-               
+
                error(1, 0, "%s error", __FUNCTION__);
        }
        return &msg_infos[idx];
@@ -294,7 +296,7 @@ int init_ftrace()
        char *debugfs;
        char path[256];
        FILE *f;
-       
+
        debugfs = "/sys/kernel/debug";
        if (debugfs) {
                strcpy(path, debugfs);
@@ -375,7 +377,7 @@ int send_frame(int socket)
        mi->length = frame.can_dlc;
        get_tstamp(&mi->ts_sent);
        mi->sent = frame;
-       
+
        trace_on();
        ret = write(socket, &frame, sizeof(frame));
        trace_off(ret);
@@ -385,6 +387,22 @@ int send_frame(int socket)
        return ret;
 }
 
+static inline send_and_check(int s)
+{
+       int ret;
+       ret = send_frame(s);
+       if (ret != sizeof(struct can_frame)) {
+/*             if (ret == -1 && errno == ENOBUFS && opt.period_us == 0 && !opt.oneattime) { */
+/*                     stats.enobufs++; */
+/*                     /\* Ignore this error - pfifo_fast qeuue is full *\/ */
+/*             } else */
+                       error(1, errno, "send_frame (line %d)", __LINE__);
+       } else {
+               count++;
+               msg_in_progress++;
+       }
+}
+
 static inline void get_next_timeout(struct timespec *timeout)
 {
        struct timespec now;
@@ -401,7 +419,10 @@ static inline void get_next_timeout(struct timespec *timeout)
                        last.tv_nsec -= 1000000000;
                        last.tv_sec++;
                }
-               timespec_subtract(timeout, &last, &now);
+               if (timespec_subtract(timeout, &last, &now) /* is negative */) {
+                       stats.overrun++;
+                       memset(timeout, 0, sizeof(*timeout));
+               }
        } else if (opt.timeout_ms != 0) {
                timeout->tv_sec = opt.timeout_ms/1000;
                timeout->tv_nsec = (opt.timeout_ms%1000)*1000000;
@@ -474,7 +495,7 @@ void process_final_rx(int s)
        struct can_frame frame;
        struct msg_info *mi;
        int ret;
-       
+
        receive(s, &frame, &ts_kern, &ts_user);
        mi = frame2info(&frame);
        mi->ts_rx_final_kern = ts_kern;
@@ -496,7 +517,6 @@ void *measure_thread(void *arg)
        struct timespec timeout;
        struct sockaddr_can addr;
        sigset_t set;
-       unsigned msg_in_progress = 0;
 
        MEMSET_ZERO(pfd);
 
@@ -538,26 +558,10 @@ void *measure_thread(void *arg)
 
        set_sched_policy_and_prio(SCHED_FIFO, 40);
 
-#define SEND()                                                         \
-       do {                                                            \
-               ret = send_frame(pfd[0].fd);                            \
-               if (ret != sizeof(struct can_frame)) {                  \
-                       if (ret == -1 && errno == ENOBUFS && opt.period_us == 0 && !opt.oneattime) { \
-                               stats.enobufs++;                        \
-                               /* Ignore this error - pfifo_fast qeuue is full */ \
-                       } else                                          \
-                               error(1, errno, "send_frame (line %d)", __LINE__); \
-               }                                                       \
-               else {                                                  \
-                       count++;                                        \
-                       msg_in_progress++;                              \
-               }                                                       \
-       } while (0)
-
-       if (opt.oneattime) {
+#define SEND() send_and_check(pfd[0].fd)
+
+       if (opt.oneattime)
                SEND();
-               count = 1;
-       }
 
        while (!finish_flag &&
               (opt.count == 0 || count < opt.count || msg_in_progress != 0)) {
@@ -672,6 +676,11 @@ int parse_options(int argc, const char *argv[])
        return 0;
 }
 
+void print_progress()
+{
+       printf("\rSent %5d, in progress %5d", count, msg_in_progress);
+       fflush(stdout);
+}
 
 int main(int argc, const char *argv[])
 {
@@ -701,7 +710,7 @@ int main(int argc, const char *argv[])
                error(1, errno, "pipe fcntl");
 
        init_ftrace();
-       
+
        pthread_create(&thread, 0, measure_thread, NULL);
 
        struct timespec next, now, diff;
@@ -728,16 +737,16 @@ int main(int argc, const char *argv[])
 
                clock_gettime(CLOCK_MONOTONIC, &now);
                if (timespec_subtract(&diff, &next, &now)) {
-                       printf("\rMessage %d", count);
-                       fflush(stdout);
-                       next.tv_nsec += 100000000;
+                       print_progress();
+                       next.tv_nsec += 100000000;
                        while (next.tv_nsec >= 1000000000) {
                                next.tv_nsec -= 1000000000;
                                next.tv_sec++;
                        }
                }
        }
-       printf("\rMessage %d\n", count);
+       print_progress();
+       printf("\n");
 
        pthread_join(thread, NULL);
 
@@ -751,5 +760,10 @@ int main(int argc, const char *argv[])
        if (opt.file)
                fclose(opt.file);
 
+       if (stats.overrun)
+               printf("overrun=%d\n", stats.overrun);
+       if (stats.enobufs)
+               printf("enobufs=%d\n", stats.enobufs);
+
        return 0;
 }