]> rtime.felk.cvut.cz Git - can-benchmark.git/blob - recvmmsg/can_recvmmsg.c
9dc57e0222799464fdddaf90a5dc013074e46524
[can-benchmark.git] / recvmmsg / can_recvmmsg.c
1 /**************************************************************************/
2 /* CAN performance benchmark for recvmmsg()                               */
3 /* Copyright (C) 2013, 2014 Michal Sojka, DCE, FEE, CTU Prague            */
4 /* License: GPLv2                                                         */
5 /**************************************************************************/
6
7 #define _GNU_SOURCE
8 #include <sys/socket.h>
9 #include <linux/can.h>
10 #include <sys/ioctl.h>
11 #include <net/if.h>
12 #include <string.h>
13 #include <unistd.h>
14 #include <stdlib.h>
15 #include <stdio.h>
16 #include <time.h>
17
18 #define CHECK(cmd) do { if ((cmd) == -1) { perror(#cmd); exit(1); } } while (0)
19
20 int count = 10000;
21
22 int main(int argc, char *argv[])
23 {
24         int ss, sr;
25         struct sockaddr_can addr;
26         struct ifreq ifr;
27         struct can_frame cf;
28         int ret, i;
29         struct timespec t1, t2;
30
31         ss = socket(PF_CAN, SOCK_RAW, CAN_RAW);
32         sr = socket(PF_CAN, SOCK_RAW, CAN_RAW);
33
34         strcpy(ifr.ifr_name, "vcan0" );
35         ioctl(ss, SIOCGIFINDEX, &ifr);
36
37         addr.can_family = AF_CAN;
38         addr.can_ifindex = ifr.ifr_ifindex;
39
40         bind(ss, (struct sockaddr *)&addr, sizeof(addr));
41         bind(sr, (struct sockaddr *)&addr, sizeof(addr));
42
43         int rcvbuf = 30 * count * sizeof(cf);
44         CHECK(setsockopt(sr, SOL_SOCKET, SO_RCVBUFFORCE, &rcvbuf, sizeof(rcvbuf)));
45
46         memset(&cf, 0, sizeof(cf));
47         cf.can_dlc = 8;
48
49         fprintf(stderr, "Sending %d frames\n", count);
50         for (i = 0; i < count; i++) {
51                 ret = write(ss, &cf, sizeof(cf));
52                 if (ret != sizeof(cf)) {
53                         perror("write");
54                         exit(1);
55                 }
56         }
57
58 #if 0
59         fprintf(stderr, "Receiving %d frames with read()\n", count);
60         for (i = 0; i < count; i++) {
61                 //fprintf(stderr, "Receiving frame %d\r", i);
62                 ret = read(sr, &cf, sizeof(cf));
63                 if (ret != sizeof(cf)) {
64                         perror("read");
65                         exit(1);
66                 }
67         }
68         //fprintf(stderr, "\n");
69 #endif
70
71         fprintf(stderr, "Receiving %d frames with recvmmsg()\n", count);
72         struct mmsghdr msgs[count];
73         struct iovec iovecs[count];
74         char bufs[count][sizeof(struct can_frame)];
75
76         memset(msgs, 0, sizeof(msgs));
77         for (i = 0; i < count; i++) {
78                 iovecs[i].iov_base         = bufs[i];
79                 iovecs[i].iov_len          = sizeof(struct can_frame);
80                 msgs[i].msg_hdr.msg_iov    = &iovecs[i];
81                 msgs[i].msg_hdr.msg_iovlen = 1;
82         }
83
84         ret = recvmmsg(sr, msgs, count, 0, NULL);
85         if (ret == -1) {
86                 perror("recvmmsg()");
87                 exit(1);
88         } else if (ret != count) {
89                 fprintf(stderr, "Error: Only %d messages received\n", ret);
90                 exit(1);
91         }
92
93         return 0;
94 }