diff options
-rw-r--r-- | benchmarks/kttcp/DESCR | 3 | ||||
-rw-r--r-- | benchmarks/kttcp/Makefile | 25 | ||||
-rw-r--r-- | benchmarks/kttcp/PLIST | 2 | ||||
-rw-r--r-- | benchmarks/kttcp/files/Makefile | 9 | ||||
-rw-r--r-- | benchmarks/kttcp/files/kttcp.c | 237 |
5 files changed, 276 insertions, 0 deletions
diff --git a/benchmarks/kttcp/DESCR b/benchmarks/kttcp/DESCR new file mode 100644 index 00000000000..a8c33dc64bb --- /dev/null +++ b/benchmarks/kttcp/DESCR @@ -0,0 +1,3 @@ +Userland portion of the "kttcp" kernel network throughput +testing tool. Uses the /dev/kttcp pseudo-device on NetBSD +systems. diff --git a/benchmarks/kttcp/Makefile b/benchmarks/kttcp/Makefile new file mode 100644 index 00000000000..a4ae400a656 --- /dev/null +++ b/benchmarks/kttcp/Makefile @@ -0,0 +1,25 @@ +# $NetBSD: Makefile,v 1.1.1.1 2002/06/29 01:07:19 thorpej Exp $ + +DISTNAME= kttcp-${VERSION} +CATEGORIES= benchmarks net +MASTER_SITES= # empty +DISTFILES= # empty + +MAINTAINER= thorpej@netbsd.org +COMMENT= kttcp kernel network throughput benchmark + +VERSION= 20020628 + +EXTRACT_ONLY= # empty +WRKSRC= ${WRKDIR} +NO_CHECKSUM= # defined + +MAKE_ENV+= BINDIR=${LOCALBASE}/bin MANDIR=${LOCALBASE}/man + +post-extract: + @for FILE in Makefile kttcp.c \ + ; do \ + ${CP} ${FILESDIR}/$$FILE ${WRKSRC}; \ + done + +.include "../../mk/bsd.pkg.mk" diff --git a/benchmarks/kttcp/PLIST b/benchmarks/kttcp/PLIST new file mode 100644 index 00000000000..2def86de3c8 --- /dev/null +++ b/benchmarks/kttcp/PLIST @@ -0,0 +1,2 @@ +@comment $NetBSD: PLIST,v 1.1.1.1 2002/06/29 01:07:19 thorpej Exp $ +bin/kttcp diff --git a/benchmarks/kttcp/files/Makefile b/benchmarks/kttcp/files/Makefile new file mode 100644 index 00000000000..fde69a64817 --- /dev/null +++ b/benchmarks/kttcp/files/Makefile @@ -0,0 +1,9 @@ +# $NetBSD: Makefile,v 1.1.1.1 2002/06/29 01:07:20 thorpej Exp $ + +PROG= kttcp +MKMAN= no +SRCS= kttcp.c + +WARNS=2 + +.include <bsd.prog.mk> diff --git a/benchmarks/kttcp/files/kttcp.c b/benchmarks/kttcp/files/kttcp.c new file mode 100644 index 00000000000..f4ef64b7f63 --- /dev/null +++ b/benchmarks/kttcp/files/kttcp.c @@ -0,0 +1,237 @@ +/* $NetBSD: kttcp.c,v 1.1.1.1 2002/06/29 01:07:20 thorpej Exp $ */ + +/* + * Copyright (c) 2002 Wasabi Systems, Inc. + * All rights reserved. + * + * Written by Frank van der Linden and Jason R. Thorpe + * for Wasabi Systems, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed for the NetBSD Project by + * Wasabi Systems, Inc. + * 4. The name of Wasabi Systems, Inc. may not be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/syscall.h> +#include <sys/ioctl.h> +#include <sys/time.h> +#include <netdb.h> +#include <unistd.h> +#include <stdio.h> +#include <err.h> +#include <fcntl.h> +#include <stdlib.h> +#include <limits.h> +#include <string.h> + +#include <dev/kttcpio.h> + +#define KTTCP_PORT "22222" +#define KTTCP_XMITSIZE (10*1024*1024) +#define KTTCP_SOCKBUF_DEFAULT 65536 + +#define KTTCP_DEVICE "/dev/kttcp" + +static void +usage(void) +{ + fprintf(stderr, + "usage: kttcp -r [-b sockbufsize] [-p port] [-q] [-c syscallnum]\n" + " [-4] [-6]\n" + " kttcp -s [-b sockbufsize] [-n bytes] [-q] [-p port]\n" + " [-c syscallnum] [-4] [-6] host\n" + ); + exit(1); +} + +int +main(int argc, char *argv[]) +{ + int c, error, s, quiet, s2, kfd; + int xmitset, family; + int bufsize; + int ai_flag; + char *host; + char *portstr; + struct kttcp_io_args kio; + struct addrinfo hints, *addr, *res; + struct sockaddr_storage ss; + unsigned long long usecs, bytespersec, xmitsize; + char connecthost[NI_MAXHOST]; + socklen_t slen; + const int one = 1; + u_long cmd; + + cmd = 0; + portstr = KTTCP_PORT; + quiet = xmitset = 0; + bufsize = KTTCP_SOCKBUF_DEFAULT; + xmitsize = KTTCP_XMITSIZE; + family = PF_UNSPEC; + while ((c = getopt(argc, argv, "46b:n:p:qrsw:")) != -1) { + switch (c) { + case '4': + if (family != PF_UNSPEC) + usage(); + family = PF_INET; + break; + case '6': + if (family != PF_UNSPEC) + usage(); + family = PF_INET6; + break; + case 'b': + bufsize = atoi(optarg); + break; + case 'n': + xmitsize = strtoll(optarg, NULL, 10); + if (xmitsize > KTTCP_MAX_XMIT) + xmitsize = KTTCP_MAX_XMIT; + xmitset = 1; + break; + case 'p': + portstr = optarg; + break; + case 'q': + quiet = 1; + break; + case 'r': + if (cmd != 0) + usage(); + cmd = KTTCP_IO_RECV; + break; + case 's': + if (cmd != 0) + usage(); + cmd = KTTCP_IO_SEND; + break; + case '?': + default: + usage(); + } + } + if (cmd == 0) + usage(); + + argc -= optind; + argv += optind; + + if (cmd == KTTCP_IO_SEND) { + if (xmitsize <= 0 || argc < 1) + usage(); + host = argv[0]; + ai_flag = 0; + } else { + if (xmitset == 0) + xmitsize = KTTCP_MAX_XMIT; + host = NULL; + ai_flag = AI_PASSIVE; + } + + if ((kfd = open(KTTCP_DEVICE, O_RDWR, 666)) == -1) + err(2, "open %s", KTTCP_DEVICE); + + memset(&hints, 0, sizeof hints); + hints.ai_flags = ai_flag; + hints.ai_socktype = SOCK_STREAM; + hints.ai_family = family; + error = getaddrinfo(host, portstr, &hints, &addr); + + if (error != 0) + errx(2, "%s", gai_strerror(error)); + + s = -1; + for (res = addr; res != NULL; res = res->ai_next) { + s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + if (s >= 0) + break; + } + if (res == NULL) + err(2, "can't create socket"); + + if (cmd == KTTCP_IO_SEND) { + if (connect(s, res->ai_addr, res->ai_addrlen) < 0) + err(2, "connect"); + if (!quiet) { + getnameinfo(res->ai_addr, res->ai_addrlen, + connecthost, sizeof connecthost, NULL, 0, + NI_NUMERICHOST); + printf("kttcp: connected to %s\n", connecthost); + } + if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof (int)) + < 0) + err(2, "setsockopt sndbuf"); + kio.kio_socket = s; + } else { + if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, + sizeof (int)) < 0) + err(2, "setsockopt reuseaddr"); + if (bind(s, res->ai_addr, res->ai_addrlen) < 0) + err(2, "bind"); + if (listen(s, 1) < 0) + err(2, "listen"); + if (!quiet) + printf("kttcp: listening on port %s\n", portstr); + slen = sizeof ss; + s2 = accept(s, (struct sockaddr *)&ss, &slen); + if (s2 < 0) + err(2, "accept"); + if (!quiet) { + getnameinfo((struct sockaddr *)&ss, ss.ss_len, + connecthost, sizeof connecthost, NULL, 0, + NI_NUMERICHOST); + printf("kttcp: connect from %s\n", connecthost); + } + if (setsockopt(s2, SOL_SOCKET, SO_RCVBUF, &bufsize, + sizeof (int)) < 0) + err(2, "setsockopt rcvbuf"); + kio.kio_socket = s2; + } + + kio.kio_totalsize = xmitsize; + + if (ioctl(kfd, cmd, &kio) == -1) + err(2, "kttcp i/o command"); + + usecs = (unsigned long long)kio.kio_elapsed.tv_sec * 1000000; + usecs += kio.kio_elapsed.tv_usec; + + bytespersec = kio.kio_bytesdone * 1000000LL / usecs; + printf("kttcp: %llu bytes in %ld.%03ld seconds ==> %llu bytes/sec\n", + kio.kio_bytesdone, kio.kio_elapsed.tv_sec, + kio.kio_elapsed.tv_usec / 1000, bytespersec); + + close(kio.kio_socket); + if (cmd == KTTCP_IO_RECV) + close(s); + close(kfd); + freeaddrinfo(addr); + + return 0; +} |