Initial version of recvmmsg benchmark
authorMichal Sojka <sojkam1@fel.cvut.cz>
Fri, 3 Jan 2014 16:50:02 +0000 (17:50 +0100)
committerMichal Sojka <sojkam1@fel.cvut.cz>
Fri, 3 Jan 2014 16:50:02 +0000 (17:50 +0100)
recvmmsg/Makefile [new file with mode: 0644]
recvmmsg/Makefile.omk [new file with mode: 0644]
recvmmsg/can_recvmmsg.c [new file with mode: 0644]

diff --git a/recvmmsg/Makefile b/recvmmsg/Makefile
new file mode 100644 (file)
index 0000000..76b56fd
--- /dev/null
@@ -0,0 +1,14 @@
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ;  while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd`  ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+       @echo -e "\nThe Makefile.rules has not been found in this or parent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
diff --git a/recvmmsg/Makefile.omk b/recvmmsg/Makefile.omk
new file mode 100644 (file)
index 0000000..b133c82
--- /dev/null
@@ -0,0 +1,7 @@
+# -*- makefile -*-
+
+bin_PROGRAMS += can_recvmmsg
+can_recvmmsg_SOURCES = can_recvmmsg.c
+can_recvmmsg_LIBS = #rt pthread m #talloc popt #ulut
+
+# OMK_CFLAGS = -DSO_RXQ_OVFL=40 -DPF_CAN=29 -DAF_CAN=PF_CAN
diff --git a/recvmmsg/can_recvmmsg.c b/recvmmsg/can_recvmmsg.c
new file mode 100644 (file)
index 0000000..9dc57e0
--- /dev/null
@@ -0,0 +1,94 @@
+/**************************************************************************/
+/* CAN performance benchmark for recvmmsg()                              */
+/* Copyright (C) 2013, 2014 Michal Sojka, DCE, FEE, CTU Prague           */
+/* License: GPLv2                                                        */
+/**************************************************************************/
+
+#define _GNU_SOURCE
+#include <sys/socket.h>
+#include <linux/can.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+
+#define CHECK(cmd) do { if ((cmd) == -1) { perror(#cmd); exit(1); } } while (0)
+
+int count = 10000;
+
+int main(int argc, char *argv[])
+{
+       int ss, sr;
+       struct sockaddr_can addr;
+       struct ifreq ifr;
+       struct can_frame cf;
+       int ret, i;
+       struct timespec t1, t2;
+
+       ss = socket(PF_CAN, SOCK_RAW, CAN_RAW);
+       sr = socket(PF_CAN, SOCK_RAW, CAN_RAW);
+
+       strcpy(ifr.ifr_name, "vcan0" );
+       ioctl(ss, SIOCGIFINDEX, &ifr);
+
+       addr.can_family = AF_CAN;
+       addr.can_ifindex = ifr.ifr_ifindex;
+
+       bind(ss, (struct sockaddr *)&addr, sizeof(addr));
+       bind(sr, (struct sockaddr *)&addr, sizeof(addr));
+
+       int rcvbuf = 30 * count * sizeof(cf);
+       CHECK(setsockopt(sr, SOL_SOCKET, SO_RCVBUFFORCE, &rcvbuf, sizeof(rcvbuf)));
+
+       memset(&cf, 0, sizeof(cf));
+       cf.can_dlc = 8;
+
+       fprintf(stderr, "Sending %d frames\n", count);
+       for (i = 0; i < count; i++) {
+               ret = write(ss, &cf, sizeof(cf));
+               if (ret != sizeof(cf)) {
+                       perror("write");
+                       exit(1);
+               }
+       }
+
+#if 0
+       fprintf(stderr, "Receiving %d frames with read()\n", count);
+       for (i = 0; i < count; i++) {
+               //fprintf(stderr, "Receiving frame %d\r", i);
+               ret = read(sr, &cf, sizeof(cf));
+               if (ret != sizeof(cf)) {
+                       perror("read");
+                       exit(1);
+               }
+       }
+       //fprintf(stderr, "\n");
+#endif
+
+       fprintf(stderr, "Receiving %d frames with recvmmsg()\n", count);
+       struct mmsghdr msgs[count];
+       struct iovec iovecs[count];
+       char bufs[count][sizeof(struct can_frame)];
+
+       memset(msgs, 0, sizeof(msgs));
+       for (i = 0; i < count; i++) {
+               iovecs[i].iov_base         = bufs[i];
+               iovecs[i].iov_len          = sizeof(struct can_frame);
+               msgs[i].msg_hdr.msg_iov    = &iovecs[i];
+               msgs[i].msg_hdr.msg_iovlen = 1;
+       }
+
+       ret = recvmmsg(sr, msgs, count, 0, NULL);
+       if (ret == -1) {
+               perror("recvmmsg()");
+               exit(1);
+       } else if (ret != count) {
+               fprintf(stderr, "Error: Only %d messages received\n", ret);
+               exit(1);
+       }
+
+       return 0;
+}