unsigned timeout_ms;
unsigned count;
unsigned oneattime;
+ char *file;
+ char *histogram_fn;
} opt = {
.id = 10,
.period_us = 0,
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;
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;
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)
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;
}
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))
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;
{ "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 }
};
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;
pthread_t thread;
sigset_t set;
int ret;
-
+ FILE *fhist;
+
parse_options(argc, argv);
mlockall(MCL_CURRENT | MCL_FUTURE);
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;
}