From 71621938d63ddfaf199741657e185d5c0a68cf3a Mon Sep 17 00:00:00 2001 From: Michal Sojka Date: Fri, 3 Jan 2014 17:50:02 +0100 Subject: [PATCH 1/1] Initial version of recvmmsg benchmark --- recvmmsg/Makefile | 14 ++++++ recvmmsg/Makefile.omk | 7 +++ recvmmsg/can_recvmmsg.c | 94 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 115 insertions(+) create mode 100644 recvmmsg/Makefile create mode 100644 recvmmsg/Makefile.omk create mode 100644 recvmmsg/can_recvmmsg.c diff --git a/recvmmsg/Makefile b/recvmmsg/Makefile new file mode 100644 index 0000000..76b56fd --- /dev/null +++ b/recvmmsg/Makefile @@ -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 index 0000000..b133c82 --- /dev/null +++ b/recvmmsg/Makefile.omk @@ -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 index 0000000..9dc57e0 --- /dev/null +++ b/recvmmsg/can_recvmmsg.c @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include + +#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; +} -- 2.39.2