]> rtime.felk.cvut.cz Git - can-benchmark.git/blobdiff - latester/latester.c
Do not call poll with negative timeout
[can-benchmark.git] / latester / latester.c
index 9f0a46654f00ba98ed1ee007ecd07520e6315571..c980f247ac9841b3aa4755aa3966880c2550865e 100644 (file)
@@ -72,6 +72,11 @@ struct options opt = {
        .length = 2,
 };
 
+struct {
+       unsigned enobufs;
+       unsigned overrun;
+} stats;
+
 int num_interfaces = 0;
 int count = 0;                 /* Number of sent messages */
 int completion_pipe[2];
@@ -232,9 +237,9 @@ static inline unsigned get_msg_latency_us(struct msg_info *mi)
        struct timespec diff;
        if (num_interfaces == 3)
                if (opt.userhist)
-                       timespec_subtract(&diff, &mi->ts_rx_final_kern, &mi->ts_rx_onwire_kern);
-               else
                        timespec_subtract(&diff, &mi->ts_rx_final, &mi->ts_rx_onwire);
+               else
+                       timespec_subtract(&diff, &mi->ts_rx_final_kern, &mi->ts_rx_onwire_kern);
        else
                if (opt.userhist)
                        timespec_subtract(&diff, &mi->ts_rx_final, &mi->ts_sent);
@@ -316,6 +321,28 @@ int init_ftrace()
 #endif /* FTRACE */
 }
 
+static inline void trace_on()
+{
+       if (trace_fd >= 0)
+               write(trace_fd, "1", 1);
+}
+
+static inline void trace_off(int ret)
+{
+       if (marker_fd >= 0) {
+               char marker[100];
+               sprintf(marker, "write returned %d\n", ret);
+               write(marker_fd, marker, strlen(marker));
+       }
+       if (trace_fd >= 0)
+               write(trace_fd, "0", 1);
+}
+
+void msg_info_free(struct msg_info *mi)
+{
+       mi->id = -1;
+}
+
 int send_frame(int socket)
 {
        struct can_frame frame;
@@ -350,22 +377,13 @@ int send_frame(int socket)
        get_tstamp(&mi->ts_sent);
        mi->sent = frame;
        
-       if (trace_fd >= 0)
-               write(trace_fd, "1", 1);
+       trace_on();
        ret = write(socket, &frame, sizeof(frame));
-       if (marker_fd >= 0) {
-               char marker[100];
-               sprintf(marker, "write returned %d\n", ret);
-               write(marker_fd, marker, strlen(marker));
-       }
-       if (trace_fd >= 0)
-               write(trace_fd, "0", 1);
-       return ret;
-}
+       trace_off(ret);
 
-void msg_info_free(struct msg_info *mi)
-{
-       mi->id = -1;
+       if (ret == -1)
+               msg_info_free(mi);
+       return ret;
 }
 
 static inline void get_next_timeout(struct timespec *timeout)
@@ -384,7 +402,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;
@@ -519,15 +540,22 @@ void *measure_thread(void *arg)
                        pfd[i].events = POLLIN;
        }
 
-       set_sched_policy_and_prio(SCHED_FIFO, 99);
-
-#define SEND()                                         \
-       do {                                            \
-               ret = send_frame(pfd[0].fd);            \
-               if (ret != sizeof(struct can_frame))    \
-                       error(1, errno, "send_frame (line %d)", __LINE__); \
-               count++;                                \
-               msg_in_progress++;                      \
+       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) {
@@ -727,5 +755,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;
 }