int opt_budget = 1024;
int opt_period = 20;
+bool opt_async = false;
struct in_addr src, dst;
{ "budget", 1, 0, 'b' },
{ "source", 1, 0, 's' },
{ "dest", 1, 0, 'd' },
+ { "async", 0, 0, 'a' },
{ 0, 0, 0, 0}
};
printf(" -b, --budget <bytes> how many bytes is sent in each period\n");
printf(" -s, --source <ip> source IP address\n");
printf(" -d, --dest <ip:port> destination IP address and port\n");
+ printf(" -a, --async Send packets asynchronously\n");
}
void parse_opts(int argc, char *argv[])
char opt;
int ret;
- while ((opt = getopt_long(argc, argv, "b:p:s:d:", long_opts, NULL)) != -1) {
+ while ((opt = getopt_long(argc, argv, "ab:p:s:d:", long_opts, NULL)) != -1) {
switch (opt) {
+ case 'a':
+ opt_async = true;
+ break;
case 'b':
opt_budget = atoi(optarg);
break;
frsh_receive_endpoint_t epdst = (frsh_receive_endpoint_t)arg;
size_t mlen;
int ret;
+ int last_cnt = -1;
struct timespec tss, tsr;
struct msg *msg;
msg = malloc(opt_budget);
ret = frsh_receive_sync(epdst, msg, opt_budget, &mlen, NULL);
clock_gettime(CLOCK_MONOTONIC, &tsr);
tss = msg->ts;
+ if (msg->cnt != last_cnt+1)
+ printf("packet(s) lost!\n");
printf("%10d: %10.3lf ms\n",
msg->cnt, tsdiff2d(&tsr, &tss)*1000);
+ last_cnt = msg->cnt;
}
return NULL;
}
if (signal(SIGINT, stopper) == SIG_ERR)
error(1, errno, "Signal handler registration error");
- struct timespec next_period, tss;
+ struct timespec next_period;
+ struct timespec tss;
clock_gettime(CLOCK_MONOTONIC, &next_period);
while (!exit_flag) {
clock_gettime(CLOCK_MONOTONIC, &tss);
msg->cnt = cnt++;
msg->ts = tss;
- ret = frsh_send_async(epsrc, msg, opt_budget);
-
- next_period.tv_nsec += opt_period * 1000000;
+ if (opt_async)
+ ret = frsh_send_async(epsrc, msg, opt_budget);
+ else {
+ ret = frsh_send_sync(epsrc, msg, opt_budget);
+ clock_gettime(CLOCK_MONOTONIC, &next_period);
+ }
+ next_period.tv_sec += (opt_period/1000);
+ next_period.tv_nsec += (opt_period%1000) * 1000000;
if (next_period.tv_nsec >= 1000000000) {
next_period.tv_nsec -= 1000000000;
next_period.tv_sec++;
}
-
clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME,
&next_period, NULL);
}