]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
rxperf: Move into the tools directory
authorSimon Wilkinson <sxw@your-file-system.com>
Tue, 17 Apr 2012 22:19:17 +0000 (23:19 +0100)
committerDerrick Brashear <shadow@dementix.org>
Thu, 19 Apr 2012 12:07:09 +0000 (05:07 -0700)
Move the 'rxperf' RX performance testing utility out of the
src/rx/test directory, and into the slightly more visible top level
src/tools/ directory

As this is the first time that rxperf has been built as part of the
default build, make a number of changes so that it will build on all
of our supported platforms.

Change-Id: Ice37e7db694dbfed34009bf76d24f1e0bf272e47
Reviewed-on: http://gerrit.openafs.org/7240
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Derrick Brashear <shadow@dementix.org>
14 files changed:
Makefile.in
NTMakefile
configure.ac
src/config/NTMakefile
src/rx/test/.gitignore
src/rx/test/NTMakefile
src/rx/test/rxperf.c [deleted file]
src/rx/test/rxperf.rc [deleted file]
src/tools/Makefile.in
src/tools/rxperf/.gitignore [new file with mode: 0644]
src/tools/rxperf/Makefile.in [new file with mode: 0644]
src/tools/rxperf/NTMakefile [new file with mode: 0644]
src/tools/rxperf/rxperf.c [new file with mode: 0644]
src/tools/rxperf/rxperf.rc [new file with mode: 0644]

index d35f4a6f3cedb2a7a3a26ef12f2b8227bfa8b042..714f2f60b0d509539efbec5cc95c239dc230bd9e 100644 (file)
@@ -909,6 +909,7 @@ distclean: clean
        src/tests/auth/Makefile \
        src/tools/Makefile \
        src/tools/dumpscan/Makefile \
+       src/tools/rxperf/Makefile \
        src/tsalvaged/Makefile \
        src/tsm41/Makefile \
        src/tvolser/Makefile \
index 3d2de46b91c88684c2a22f3bceeb0bbf2c7c64ae..0f1fa1b6e280f7999c06cc63307e75cf84057a94 100644 (file)
@@ -714,8 +714,15 @@ extra: afsrdr rpctestlib
 !      ELSE
      @echo ***** Skipping $@ ***** Not found.
 !      ENDIF
-                
-finale: extra
+
+tools: extra
+     @echo ***** $@
+       $(DOCD) $(SRC)\tools\rxperf
+       $(CD) $(SRC)\tools\rxperf
+       $(NTMAKE)
+       $(CD) ..\..\..
+
+finale: tools
      @echo ***** $@
        $(DOCD) $(SRC)\$@
        $(CD) $(SRC)\$@
index 6d3dc5ce8b303505b853329429a1ff91352560d7..35c8694351af93e72bb686f59b0e0f1e57b80581 100644 (file)
@@ -229,6 +229,7 @@ src/tests/Makefile \
 src/tests/run-tests \
 src/tools/Makefile \
 src/tools/dumpscan/Makefile \
+src/tools/rxperf/Makefile \
 src/tsalvaged/Makefile \
 src/tsm41/Makefile \
 src/tvolser/Makefile \
index ff94d5c61ccff201ba9455237c131568b008272b..cefdaee5c79fc7350304608894b21d07d2afda1c 100644 (file)
@@ -214,6 +214,12 @@ idirs: doclink
 !      IF (!EXIST($(OJT)\tvolser))
                $(MKDIR) $(OJT)\tvolser
 !      ENDIF
+!      IF (!EXIST($(OJT)\tools))
+               $(MKDIR) $(OJT)\tools
+!      ENDIF
+!      IF (!EXIST($(OJT)\tools\rxperf))
+               $(MKDIR) $(OJT)\tools\rxperf
+!      ENDIF
 !      IF (!EXIST($(OJT)\dviced))
                $(MKDIR) $(OJT)\dviced
 !      ENDIF
index c99ab9962f3f298f499791943afd35e85736f11d..f1fecd2ebe3d23e19a6767cc7a7867381728fb85 100644 (file)
@@ -2,7 +2,6 @@
 #     git ls-files -i --exclude-standard
 # to check that you haven't inadvertently ignored any tracked files.
 
-/rxperf
 /testclient
 /testserver
 /generator
index 3fa8ed5dabfb286e4d8f91e7b4f83307e03f2476..38fa7df2e0348560ec9cd8ff76628c776d6767fb 100644 (file)
@@ -25,15 +25,7 @@ LIBS = \
 
 RXTESTOBJS = $(OUT)\testclient.obj $(OUT)\testserver.obj
 
-tests: $(OUT)\rxperf.exe $(OUT)\testclient.exe $(OUT)\testserver.exe $(OUT)\tableGen.exe $(OUT)\generator.exe
-
-$(OUT)\rxperf.res: rxperf.rc AFS_component_version_number.h
-
-$(OUT)\rxperf.exe: $(OUT)\rxperf.obj $(OUT)\rxperf.res $(LIBS)
-       $(EXECONLINK)
-        $(_VC_MANIFEST_EMBED_EXE)
-        $(CODESIGN_USERLAND)
-        $(SYMSTORE_IMPORT)
+tests: $(OUT)\testclient.exe $(OUT)\testserver.exe $(OUT)\tableGen.exe $(OUT)\generator.exe
 
 $(OUT)\testclient.exe: $(OUT)\testclient.obj $(LIBS)
        $(EXECONLINK)
@@ -66,4 +58,4 @@ mkdir:
 install: tests
 
 clean::
-    $(DEL) $(TESTS) $(OUT)\rxperf.res
+    $(DEL) $(TESTS)
diff --git a/src/rx/test/rxperf.c b/src/rx/test/rxperf.c
deleted file mode 100644 (file)
index 67f2418..0000000
+++ /dev/null
@@ -1,1222 +0,0 @@
-/*
- * Copyright (c) 2000 - 2001 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden).
- * All rights reserved.
- *
- * 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
- *    at such time that OpenAFS documentation is written.
- *
- * 3. Neither the name of the Institute nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 THE INSTITUTE OR CONTRIBUTORS 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 <afsconfig.h>
-
-/*
-nn * We are using getopt since we want it to be possible to link to
- * transarc libs.
- */
-
-#include <afsconfig.h>
-#include <afs/param.h>
-#include <roken.h>
-
-#ifdef HAVE_SYS_FILE_H
-#include <sys/file.h>
-#endif
-
-#include <assert.h>
-
-#include <rx/rx.h>
-#include <rx/rx_null.h>
-#include <rx/rx_globals.h>
-#include <rx/rx_packet.h>
-
-#ifdef AFS_PTHREAD_ENV
-#include <pthread.h>
-#define MAX_THREADS 128
-#endif
-
-static const char *__progname;
-
-#ifndef HAVE_WARNX
-static void
-warnx(const char *fmt, ...)
-{
-    va_list args;
-
-    va_start(args, fmt);
-    fprintf(stderr, "%s: ", __progname);
-    vfprintf(stderr, fmt, args);
-    fprintf(stderr, "\n");
-    va_end(args);
-}
-#endif /* !HAVE_WARNX */
-
-#ifndef HAVE_ERRX
-static void
-errx(int eval, const char *fmt, ...)
-{
-    va_list args;
-
-    va_start(args, fmt);
-    fprintf(stderr, "%s: ", __progname);
-    vfprintf(stderr, fmt, args);
-    fprintf(stderr, "\n");
-    va_end(args);
-
-    exit(eval);
-}
-#endif /* !HAVE_ERRX */
-
-#ifndef HAVE_WARN
-static void
-warn(const char *fmt, ...)
-{
-    va_list args;
-    char *errstr;
-
-    va_start(args, fmt);
-    fprintf(stderr, "%s: ", __progname);
-    vfprintf(stderr, fmt, args);
-
-    errstr = strerror(errno);
-
-    fprintf(stderr, ": %s\n", errstr ? errstr : "unknown error");
-    va_end(args);
-}
-#endif /* !HAVE_WARN */
-
-#ifndef HAVE_ERR
-static void
-err(int eval, const char *fmt, ...)
-{
-    va_list args;
-    char *errstr;
-
-    va_start(args, fmt);
-    fprintf(stderr, "%s: ", __progname);
-    vfprintf(stderr, fmt, args);
-
-    errstr = strerror(errno);
-
-    fprintf(stderr, ": %s\n", errstr ? errstr : "unknown error");
-    va_end(args);
-
-    exit(eval);
-}
-#endif /* !HAVE_ERR */
-
-#define DEFAULT_PORT 7009      /* To match tcpdump */
-#define DEFAULT_HOST "127.0.0.1"
-#define DEFAULT_BYTES 1024 * 1024
-#define RXPERF_BUFSIZE 512 * 1024
-
-enum { RX_PERF_VERSION = 3 };
-enum { RX_SERVER_ID = 147 };
-enum { RX_PERF_UNKNOWN = -1,
-       RX_PERF_SEND = 0,
-       RX_PERF_RECV = 1,
-       RX_PERF_RPC = 3,
-       RX_PERF_FILE = 4
-};
-
-enum { RXPERF_MAGIC_COOKIE = 0x4711 };
-
-/*
- *
- */
-
-#if RXPERF_DEBUG
-#define DBFPRINT(x) do { printf x ; } while(0)
-#else
-#define DBFPRINT(x)
-#endif
-
-static void
-sigusr1(int foo)
-{
-    exit(2);                   /* XXX profiler */
-}
-
-static void
-sigint(int foo)
-{
-    rx_Finalize();
-    exit(2);                   /* XXX profiler */
-}
-
-/*
- *
- */
-
-static struct timeval timer_start;
-static struct timeval timer_stop;
-static int timer_check = 0;
-
-static void
-start_timer(void)
-{
-    timer_check++;
-    gettimeofday(&timer_start, NULL);
-}
-
-/*
- *
- */
-
-static void
-end_and_print_timer(char *str)
-{
-    long long start_l, stop_l;
-
-    timer_check--;
-    assert(timer_check == 0);
-    gettimeofday(&timer_stop, NULL);
-    start_l = timer_start.tv_sec * 1000000 + timer_start.tv_usec;
-    stop_l = timer_stop.tv_sec * 1000000 + timer_stop.tv_usec;
-    printf("%s:\t%8llu msec\n", str, (stop_l - start_l) / 1000);
-}
-
-/*
- *
- */
-
-static u_long
-str2addr(const char *s)
-{
-    struct in_addr server;
-    struct hostent *h;
-
-#ifndef INADDR_NONE
-#define INADDR_NONE 0xffffffff
-#endif
-    if (inet_addr(s) != INADDR_NONE)
-       return inet_addr(s);
-    h = gethostbyname(s);
-    if (h != NULL) {
-       memcpy(&server, h->h_addr_list[0], sizeof(server));
-       return server.s_addr;
-    }
-    return 0;
-}
-
-
-/*
- *
- */
-
-static void
-get_sec(int serverp, struct rx_securityClass **sec, int *secureindex)
-{
-    if (serverp) {
-       *sec = rxnull_NewServerSecurityObject();
-       *secureindex = 1;
-    } else {
-       *sec = rxnull_NewClientSecurityObject();
-       *secureindex = 0;
-    }
-}
-
-/*
- * process the "RPC" and return the results
- */
-
-char somebuf[RXPERF_BUFSIZE];
-
-afs_int32 rxwrite_size = sizeof(somebuf);
-afs_int32 rxread_size = sizeof(somebuf);
-afs_int32 use_rx_readv = 0;
-
-static int
-do_readbytes(struct rx_call *call, afs_int32 bytes)
-{
-    struct iovec tiov[RX_MAXIOVECS];
-    afs_int32 size;
-    int tnio;
-    int code;
-
-    while (bytes > 0) {
-       size = rxread_size;
-
-       if (size > bytes)
-           size = bytes;
-       if (use_rx_readv) {
-            if (size > RX_MAX_PACKET_DATA_SIZE)
-                size = RX_MAX_PACKET_DATA_SIZE;
-            code = rx_Readv(call, tiov, &tnio, RX_MAXIOVECS, size);
-        } else
-            code = rx_Read(call, somebuf, size);
-        if (code != size)
-            return 1;
-
-       bytes -= size;
-    }
-    return 0;
-}
-
-static int
-do_sendbytes(struct rx_call *call, afs_int32 bytes)
-{
-    afs_int32 size;
-
-    while (bytes > 0) {
-       size = rxwrite_size;
-       if (size > bytes)
-           size = bytes;
-       if (rx_Write(call, somebuf, size) != size)
-           return 1;
-       bytes -= size;
-    }
-    return 0;
-}
-
-
-static afs_int32
-rxperf_ExecuteRequest(struct rx_call *call)
-{
-    afs_int32 version;
-    afs_int32 command;
-    afs_int32 bytes;
-    afs_int32 recvb;
-    afs_int32 sendb;
-    afs_int32 data;
-    afs_uint32 num;
-    afs_uint32 *readwrite;
-    afs_uint32 i;
-    int readp = TRUE;
-
-    DBFPRINT(("got a request\n"));
-
-    if (rx_Read32(call, &version) != 4) {
-       warn("rx_Read failed to read version");
-       return -1;
-    }
-
-    if (htonl(RX_PERF_VERSION) != version) {
-       warnx("client has wrong version");
-       return -1;
-    }
-
-    if (rx_Read32(call, &command) != 4) {
-       warnx("rx_Read failed to read command");
-       return -1;
-    }
-    command = ntohl(command);
-
-    if (rx_Read32(call, &data) != 4) {
-       warnx("rx_Read failed to read size");
-       return -1;
-    }
-    rxread_size = ntohl(data);
-    if (rxread_size > sizeof(somebuf)) {
-       warnx("rxread_size too large %d", rxread_size);
-       return -1;
-    }
-
-    if (rx_Read32(call, &data) != 4) {
-       warnx("rx_Read failed to write size");
-       return -1;
-    }
-    rxwrite_size = ntohl(data);
-    if (rxwrite_size > sizeof(somebuf)) {
-       warnx("rxwrite_size too large %d", rxwrite_size);
-       return -1;
-    }
-
-    switch (command) {
-    case RX_PERF_SEND:
-       DBFPRINT(("got a send request\n"));
-
-       if (rx_Read32(call, &bytes) != 4) {
-           warnx("rx_Read failed to read bytes");
-           return -1;
-       }
-       bytes = ntohl(bytes);
-
-       DBFPRINT(("reading(%d) ", bytes));
-       do_readbytes(call, bytes);
-
-       data = htonl(RXPERF_MAGIC_COOKIE);
-       if (rx_Write32(call, &data) != 4) {
-           warnx("rx_Write failed when sending back result");
-           return -1;
-       }
-       DBFPRINT(("done\n"));
-
-       break;
-    case RX_PERF_RPC:
-       DBFPRINT(("got a rpc request, reading commands\n"));
-
-       if (rx_Read32(call, &recvb) != 4) {
-           warnx("rx_Read failed to read recvbytes");
-           return -1;
-       }
-       recvb = ntohl(recvb);
-       if (rx_Read32(call, &sendb) != 4) {
-           warnx("rx_Read failed to read sendbytes");
-           return -1;
-       }
-       sendb = ntohl(sendb);
-
-       DBFPRINT(("read(%d) ", recvb));
-       if (do_readbytes(call, recvb)) {
-           warnx("do_readbytes failed");
-           return -1;
-       }
-       DBFPRINT(("send(%d) ", sendb));
-       if (do_sendbytes(call, sendb)) {
-           warnx("sendbytes failed");
-           return -1;
-       }
-
-       DBFPRINT(("done\n"));
-
-       data = htonl(RXPERF_MAGIC_COOKIE);
-       if (rx_Write32(call, &data) != 4) {
-           warnx("rx_Write failed when sending back magic cookie");
-           return -1;
-       }
-
-       break;
-    case RX_PERF_FILE:
-       if (rx_Read32(call, &data) != 4)
-           errx(1, "failed to read num from client");
-       num = ntohl(data);
-
-       readwrite = malloc(num * sizeof(afs_uint32));
-       if (readwrite == NULL)
-           err(1, "malloc");
-
-       if (rx_Read(call, (char*)readwrite, num * sizeof(afs_uint32)) !=
-           num * sizeof(afs_uint32))
-           errx(1, "failed to read recvlist from client");
-
-       for (i = 0; i < num; i++) {
-           if (readwrite[i] == 0) {
-               DBFPRINT(("readp %d", readwrite[i]));
-               readp = !readp;
-           }
-
-           bytes = ntohl(readwrite[i]) * sizeof(afs_uint32);
-
-           if (readp) {
-               DBFPRINT(("read\n"));
-               do_readbytes(call, bytes);
-           } else {
-               do_sendbytes(call, bytes);
-               DBFPRINT(("send\n"));
-           }
-       }
-
-       break;
-    case RX_PERF_RECV:
-       DBFPRINT(("got a recv request\n"));
-
-       if (rx_Read32(call, &bytes) != 4) {
-           warnx("rx_Read failed to read bytes");
-           return -1;
-       }
-       bytes = ntohl(bytes);
-
-       DBFPRINT(("sending(%d) ", bytes));
-       do_sendbytes(call, bytes);
-
-       data = htonl(RXPERF_MAGIC_COOKIE);
-       if (rx_Write32(call, &data) != 4) {
-           warnx("rx_Write failed when sending back result");
-           return -1;
-       }
-       DBFPRINT(("done\n"));
-
-       break;
-    default:
-       warnx("client sent a unsupported command");
-       return -1;
-    }
-    DBFPRINT(("done with command\n"));
-
-    return 0;
-}
-
-/*
- *
- */
-
-static void
-do_server(short port, int nojumbo, int maxmtu, int maxwsize, int minpeertimeout,
-          int udpbufsz, int nostats, int hotthread,
-          int minprocs, int maxprocs)
-{
-    struct rx_service *service;
-    struct rx_securityClass *secureobj;
-    int secureindex;
-    int ret;
-
-#ifdef AFS_NT40_ENV
-    if (afs_winsockInit() < 0) {
-       printf("Can't initialize winsock.\n");
-       exit(1);
-    }
-#endif
-
-    if (hotthread)
-        rx_EnableHotThread();
-
-    if (nostats)
-        rx_enable_stats = 0;
-
-    rx_SetUdpBufSize(udpbufsz);
-
-    ret = rx_Init(htons(port));
-    if (ret)
-       errx(1, "rx_Init failed");
-
-    if (nojumbo)
-      rx_SetNoJumbo();
-
-    if (maxmtu)
-      rx_SetMaxMTU(maxmtu);
-
-    if (maxwsize) {
-        rx_SetMaxReceiveWindow(maxwsize);
-        rx_SetMaxSendWindow(maxwsize);
-    }
-
-    if (minpeertimeout)
-        rx_SetMinPeerTimeout(minpeertimeout);
-
-
-    get_sec(1, &secureobj, &secureindex);
-
-    service =
-       rx_NewService(0, RX_SERVER_ID, "rxperf", &secureobj, secureindex,
-                     rxperf_ExecuteRequest);
-    if (service == NULL)
-       errx(1, "Cant create server");
-
-    rx_SetMinProcs(service, minprocs);
-    rx_SetMaxProcs(service, maxprocs);
-
-    rx_SetCheckReach(service, 1);
-
-    rx_StartServer(1);
-
-    abort();
-}
-
-/*
- *
- */
-
-static void
-readfile(const char *filename, afs_uint32 ** readwrite, afs_uint32 * size)
-{
-    FILE *f;
-    afs_uint32 len = 16;
-    afs_uint32 num = 0;
-    afs_uint32 data;
-    char *ptr;
-    char *buf;
-
-    *readwrite = malloc(sizeof(afs_uint32) * len);
-    buf = malloc(RXPERF_BUFSIZE);
-
-    if (*readwrite == NULL)
-       err(1, "malloc");
-
-    f = fopen(filename, "r");
-    if (f == NULL)
-       err(1, "fopen");
-
-    while (fgets(buf, sizeof(buf), f) != NULL) {
-       if (num >= len) {
-           len = len * 2;
-           *readwrite = realloc(*readwrite, len * sizeof(afs_uint32));
-           if (*readwrite == NULL)
-               err(1, "realloc");
-       }
-
-       if (*buf != '\n') {
-           data = htonl(strtol(buf, &ptr, 0));
-           if (ptr && ptr == buf)
-               errx(1, "can't resolve number of bytes to transfer");
-       } else {
-           data = 0;
-       }
-
-       (*readwrite)[num] = data;
-       num++;
-    }
-
-    *size = num;
-
-
-    if (fclose(f) == -1)
-       err(1, "fclose");
-    free(buf);
-}
-
-struct client_data {
-    struct rx_connection *conn;
-    char *filename;
-    int command;
-    afs_int32 times;
-    afs_int32 bytes;
-    afs_int32 sendbytes;
-    afs_int32 readbytes;
-};
-
-static void *
-client_thread( void *vparams)
-{
-    struct client_data *params = (struct client_data *)vparams;
-    struct rx_call *call;
-    afs_int32 data;
-    int i, j;
-    afs_uint32 *readwrite;
-    int readp = FALSE;
-    afs_uint32 size;
-    afs_uint32 num;
-
-    for (i = 0; i < params->times; i++) {
-
-       DBFPRINT(("starting command "));
-
-       call = rx_NewCall(params->conn);
-       if (call == NULL)
-           errx(1, "rx_NewCall failed");
-
-       data = htonl(RX_PERF_VERSION);
-       if (rx_Write32(call, &data) != 4)
-           errx(1, "rx_Write failed to send version (err %d)", rx_Error(call));
-
-       data = htonl(params->command);
-       if (rx_Write32(call, &data) != 4)
-           errx(1, "rx_Write failed to send command (err %d)", rx_Error(call));
-
-       data = htonl(rxread_size);
-       if (rx_Write32(call, &data) != 4)
-           errx(1, "rx_Write failed to send read size (err %d)", rx_Error(call));
-       data = htonl(rxwrite_size);
-       if (rx_Write32(call, &data) != 4)
-           errx(1, "rx_Write failed to send write read (err %d)", rx_Error(call));
-
-
-       switch (params->command) {
-       case RX_PERF_RECV:
-           DBFPRINT(("command "));
-
-           data = htonl(params->bytes);
-           if (rx_Write32(call, &data) != 4)
-               errx(1, "rx_Write failed to send size (err %d)", rx_Error(call));
-
-           DBFPRINT(("sending(%d) ", params->bytes));
-           if (do_readbytes(call, params->bytes))
-               errx(1, "sendbytes (err %d)", rx_Error(call));
-
-           if (rx_Read32(call, &data) != 4)
-               errx(1, "failed to read result from server (err %d)", rx_Error(call));
-
-           if (data != htonl(RXPERF_MAGIC_COOKIE))
-               warn("server send wrong magic cookie in responce");
-
-           DBFPRINT(("done\n"));
-
-           break;
-       case RX_PERF_SEND:
-           DBFPRINT(("command "));
-
-           data = htonl(params->bytes);
-           if (rx_Write32(call, &data) != 4)
-               errx(1, "rx_Write failed to send size (err %d)", rx_Error(call));
-
-           DBFPRINT(("sending(%d) ", params->bytes));
-           if (do_sendbytes(call, params->bytes))
-               errx(1, "sendbytes (err %d)", rx_Error(call));
-
-           if (rx_Read32(call, &data) != 4)
-               errx(1, "failed to read result from server (err %d)", rx_Error(call));
-
-           if (data != htonl(RXPERF_MAGIC_COOKIE))
-               warn("server send wrong magic cookie in responce");
-
-           DBFPRINT(("done\n"));
-
-           break;
-       case RX_PERF_RPC:
-           DBFPRINT(("commands "));
-
-           data = htonl(params->sendbytes);
-           if (rx_Write32(call, &data) != 4)
-               errx(1, "rx_Write failed to send command (err %d)", rx_Error(call));
-
-           data = htonl(params->readbytes);
-           if (rx_Write32(call, &data) != 4)
-               errx(1, "rx_Write failed to send command (err %d)", rx_Error(call));
-
-           DBFPRINT(("send(%d) ", params->sendbytes));
-           if (do_sendbytes(call, params->sendbytes))
-               errx(1, "sendbytes (err %d)", rx_Error(call));
-
-           DBFPRINT(("recv(%d) ", params->readbytes));
-           if (do_readbytes(call, params->readbytes))
-               errx(1, "sendbytes (err %d)", rx_Error(call));
-
-           if (rx_Read32(call, &data) != 4)
-               errx(1, "failed to read result from server (err %d)", rx_Error(call));
-
-           if (data != htonl(RXPERF_MAGIC_COOKIE))
-               warn("server send wrong magic cookie in responce");
-
-           DBFPRINT(("done\n"));
-
-           break;
-
-       case RX_PERF_FILE:
-           readfile(params->filename, &readwrite, &num);
-
-           data = htonl(num);
-           if (rx_Write32(call, &data) != 4)
-               errx(1, "rx_Write failed to send size (err %d)", rx_Error(call));
-
-           if (rx_Write(call, (char *)readwrite, num * sizeof(afs_uint32))
-               != num * sizeof(afs_uint32))
-               errx(1, "rx_Write failed to send list (err %d)", rx_Error(call));
-
-           for (j = 0; j < num; j++) {
-               if (readwrite[j] == 0)
-                   readp = !readp;
-
-               size = ntohl(readwrite[j]) * sizeof(afs_uint32);
-
-               if (readp) {
-                   if (do_readbytes(call, size))
-                       errx(1, "sendbytes (err %d)", rx_Error(call));
-                   DBFPRINT(("read\n"));
-               } else {
-                   if (do_sendbytes(call, size))
-                       errx(1, "sendbytes (err %d)", rx_Error(call));
-                   DBFPRINT(("send\n"));
-               }
-           }
-           break;
-       default:
-           abort();
-       }
-
-       rx_EndCall(call, 0);
-    }
-
-#ifdef AFS_PTHREAD_ENV
-    pthread_exit(NULL);
-#endif
-
-    return NULL;
-}
-
-/*
- *
- */
-
-static void
-do_client(const char *server, short port, char *filename, afs_int32 command,
-         afs_int32 times, afs_int32 bytes, afs_int32 sendbytes, afs_int32 readbytes,
-          int dumpstats, int nojumbo, int maxmtu, int maxwsize, int minpeertimeout,
-          int udpbufsz, int nostats, int hotthread, int threads)
-{
-    struct rx_connection *conn;
-    afs_uint32 addr;
-    struct rx_securityClass *secureobj;
-    int secureindex;
-    int ret;
-    char stamp[2048];
-    struct client_data *params;
-
-#ifdef AFS_PTHREAD_ENV
-    int i;
-    pthread_t thread[MAX_THREADS];
-    pthread_attr_t tattr;
-    void *status;
-#endif
-
-    params = malloc(sizeof(struct client_data));
-    memset(params, 0, sizeof(struct client_data));
-
-#ifdef AFS_NT40_ENV
-    if (afs_winsockInit() < 0) {
-       printf("Can't initialize winsock.\n");
-       exit(1);
-    }
-#endif
-
-    if (hotthread)
-        rx_EnableHotThread();
-
-    if (nostats)
-        rx_enable_stats = 0;
-
-    addr = str2addr(server);
-
-    rx_SetUdpBufSize(udpbufsz);
-
-    ret = rx_Init(0);
-    if (ret)
-       errx(1, "rx_Init failed");
-
-    if (nojumbo)
-      rx_SetNoJumbo();
-
-    if (maxmtu)
-      rx_SetMaxMTU(maxmtu);
-
-    if (maxwsize) {
-        rx_SetMaxReceiveWindow(maxwsize);
-        rx_SetMaxSendWindow(maxwsize);
-    }
-
-    if (minpeertimeout)
-        rx_SetMinPeerTimeout(minpeertimeout);
-
-
-    get_sec(0, &secureobj, &secureindex);
-
-    switch (command) {
-    case RX_PERF_RPC:
-        sprintf(stamp, "RPC: threads\t%d, times\t%d, write bytes\t%d, read bytes\t%d",
-                 threads, times, sendbytes, readbytes);
-        break;
-    case RX_PERF_RECV:
-        sprintf(stamp, "RECV: threads\t%d, times\t%d, bytes\t%d",
-                 threads, times, bytes);
-        break;
-    case RX_PERF_SEND:
-        sprintf(stamp, "SEND: threads\t%d, times\t%d, bytes\t%d",
-                 threads, times, bytes);
-        break;
-    case RX_PERF_FILE:
-        sprintf(stamp, "FILE %s: threads\t%d, times\t%d, bytes\t%d",
-                 filename, threads, times, bytes);
-        break;
-    }
-
-    conn = rx_NewConnection(addr, htons(port), RX_SERVER_ID, secureobj, secureindex);
-    if (conn == NULL)
-       errx(1, "failed to contact server");
-
-#ifdef AFS_PTHREAD_ENV
-    pthread_attr_init(&tattr);
-    pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_JOINABLE);
-#endif
-
-    params->conn = conn;
-    params->filename = filename;
-    params->command = command;
-    params->times = times;
-    params->bytes = bytes;
-    params->sendbytes = sendbytes;
-    params->readbytes = readbytes;
-
-    start_timer();
-
-#ifdef AFS_PTHREAD_ENV
-    for ( i=0; i<threads; i++) {
-        pthread_create(&thread[i], &tattr, client_thread, params);
-        if ( (i + 1) % RX_MAXCALLS == 0 ) {
-            conn = rx_NewConnection(addr, htons(port), RX_SERVER_ID, secureobj, secureindex);
-            if (conn != NULL) {
-                struct client_data *new_params = malloc(sizeof(struct client_data));
-                memcpy(new_params, params, sizeof(struct client_data));
-                new_params->conn = conn;
-                params = new_params;
-            }
-        }
-    }
-#else
-        client_thread(params);
-#endif
-
-#ifdef AFS_PTHREAD_ENV
-    for ( i=0; i<threads; i++)
-        pthread_join(thread[i], &status);
-#endif
-
-    end_and_print_timer(stamp);
-    DBFPRINT(("done for good\n"));
-
-    if (dumpstats) {
-       rx_PrintStats(stdout);
-       rx_PrintPeerStats(stdout, rx_PeerOf(conn));
-    }
-    rx_Finalize();
-
-#ifdef AFS_PTHREAD_ENV
-    pthread_attr_destroy(&tattr);
-#endif
-
-    free(params);
-}
-
-static void
-usage(void)
-{
-#define COMMON ""
-
-    fprintf(stderr, "usage: %s client -c send -b <bytes>\n", __progname);
-    fprintf(stderr, "usage: %s client -c recv -b <bytes>\n", __progname);
-    fprintf(stderr,
-           "usage: %s client -c rpc  -S <sendbytes> -R <recvbytes>\n",
-           __progname);
-    fprintf(stderr, "usage: %s client -c file -f filename\n", __progname);
-    fprintf(stderr,
-           "%s: usage: common option to the client "
-           "-w <write-bytes> -r <read-bytes> -T times -p port -s server -D\n",
-           __progname);
-    fprintf(stderr, "usage: %s server -p port\n", __progname);
-#undef COMMMON
-    exit(1);
-}
-
-
-
-/*
- * do argument processing and call networking functions
- */
-
-static int
-rxperf_server(int argc, char **argv)
-{
-    short port = DEFAULT_PORT;
-    int nojumbo = 0;
-    int maxmtu = 0;
-    int nostats = 0;
-    int udpbufsz = 64 * 1024;
-    int hotthreads = 0;
-    int minprocs = 2;
-    int maxprocs = 20;
-    int maxwsize = 0;
-    int minpeertimeout = 0;
-    char *ptr;
-    int ch;
-
-    while ((ch = getopt(argc, argv, "r:d:p:P:w:W:HNjm:u:4:s:S:V")) != -1) {
-       switch (ch) {
-       case 'd':
-#ifdef RXDEBUG
-           rx_debugFile = fopen(optarg, "w");
-           if (rx_debugFile == NULL)
-               err(1, "fopen %s", optarg);
-#else
-           errx(1, "compiled without RXDEBUG");
-#endif
-           break;
-       case 'r':
-           rxread_size = strtol(optarg, &ptr, 0);
-           if (ptr != 0 && ptr[0] != '\0')
-               errx(1, "can't resolve readsize");
-           if (rxread_size > sizeof(somebuf))
-               errx(1, "%d > sizeof(somebuf) (%"AFS_SIZET_FMT")", rxread_size,
-                    sizeof(somebuf));
-           break;
-       case 's':
-           minprocs = strtol(optarg, &ptr, 0);
-           if (ptr != 0 && ptr[0] != '\0')
-               errx(1, "can't resolve minprocs");
-           break;
-       case 'S':
-           maxprocs = strtol(optarg, &ptr, 0);
-           if (ptr != 0 && ptr[0] != '\0')
-               errx(1, "can't resolve maxprocs");
-           break;
-       case 'P':
-           minpeertimeout = strtol(optarg, &ptr, 0);
-           if (ptr != 0 && ptr[0] != '\0')
-               errx(1, "can't resolve min peer timeout");
-           break;
-       case 'p':
-           port = (short) strtol(optarg, &ptr, 0);
-           if (ptr != 0 && ptr[0] != '\0')
-               errx(1, "can't resolve portname");
-           break;
-       case 'w':
-           rxwrite_size = strtol(optarg, &ptr, 0);
-           if (ptr != 0 && ptr[0] != '\0')
-               errx(1, "can't resolve writesize");
-           if (rxwrite_size > sizeof(somebuf))
-               errx(1, "%d > sizeof(somebuf) (%"AFS_SIZET_FMT")", rxwrite_size,
-                    sizeof(somebuf));
-           break;
-       case 'j':
-         nojumbo=1;
-         break;
-       case 'N':
-         nostats=1;
-         break;
-       case 'H':
-           hotthreads = 1;
-           break;
-       case 'm':
-         maxmtu = strtol(optarg, &ptr, 0);
-         if (ptr && *ptr != '\0')
-           errx(1, "can't resolve rx maxmtu to use");
-           break;
-       case 'u':
-           udpbufsz = strtol(optarg, &ptr, 0) * 1024;
-           if (ptr && *ptr != '\0')
-               errx(1, "can't resolve upd buffer size (Kbytes)");
-           break;
-       case 'V':
-           use_rx_readv = 1;
-           break;
-       case 'W':
-           maxwsize = strtol(optarg, &ptr, 0);
-           if (ptr && *ptr != '\0')
-               errx(1, "can't resolve max send/recv window size (packets)");
-           break;
-       case '4':
-         RX_IPUDP_SIZE = 28;
-         break;
-       default:
-           usage();
-       }
-    }
-
-    if (optind != argc)
-       usage();
-
-    do_server(port, nojumbo, maxmtu, maxwsize, minpeertimeout, udpbufsz,
-              nostats, hotthreads, minprocs, maxprocs);
-
-    return 0;
-}
-
-/*
- * do argument processing and call networking functions
- */
-
-static int
-rxperf_client(int argc, char **argv)
-{
-    char *host = DEFAULT_HOST;
-    int bytes = DEFAULT_BYTES;
-    short port = DEFAULT_PORT;
-    char *filename = NULL;
-    afs_int32 cmd;
-    int sendbytes = 3;
-    int readbytes = 30;
-    int times = 100;
-    int dumpstats = 0;
-    int nojumbo = 0;
-    int nostats = 0;
-    int maxmtu = 0;
-    int hotthreads = 0;
-    int threads = 1;
-    int udpbufsz = 64 * 1024;
-    int maxwsize = 0;
-    int minpeertimeout = 0;
-    char *ptr;
-    int ch;
-
-    cmd = RX_PERF_UNKNOWN;
-
-    while ((ch = getopt(argc, argv, "T:S:R:b:c:d:p:P:r:s:w:W:f:HDNjm:u:4:t:V")) != -1) {
-       switch (ch) {
-       case 'b':
-           bytes = strtol(optarg, &ptr, 0);
-           if (ptr && *ptr != '\0')
-               errx(1, "can't resolve number of bytes to transfer");
-           break;
-       case 'c':
-           if (strcasecmp(optarg, "send") == 0)
-               cmd = RX_PERF_SEND;
-           else if (strcasecmp(optarg, "recv") == 0)
-               cmd = RX_PERF_RECV;
-           else if (strcasecmp(optarg, "rpc") == 0)
-               cmd = RX_PERF_RPC;
-           else if (strcasecmp(optarg, "file") == 0)
-               cmd = RX_PERF_FILE;
-           else
-               errx(1, "unknown command %s", optarg);
-           break;
-       case 'd':
-#ifdef RXDEBUG
-           rx_debugFile = fopen(optarg, "w");
-           if (rx_debugFile == NULL)
-               err(1, "fopen %s", optarg);
-#else
-           errx(1, "compiled without RXDEBUG");
-#endif
-           break;
-       case 'P':
-           minpeertimeout = strtol(optarg, &ptr, 0);
-           if (ptr != 0 && ptr[0] != '\0')
-               errx(1, "can't resolve min peer timeout");
-           break;
-       case 'p':
-           port = (short) strtol(optarg, &ptr, 0);
-           if (ptr != 0 && ptr[0] != '\0')
-               errx(1, "can't resolve portname");
-           break;
-       case 'r':
-           rxread_size = strtol(optarg, &ptr, 0);
-           if (ptr != 0 && ptr[0] != '\0')
-               errx(1, "can't resolve readsize");
-           if (rxread_size > sizeof(somebuf))
-               errx(1, "%d > sizeof(somebuf) (%"AFS_SIZET_FMT")", rxread_size,
-                    sizeof(somebuf));
-           break;
-       case 's':
-           host = strdup(optarg);
-           if (host == NULL)
-               err(1, "strdup");
-           break;
-       case 'V':
-           use_rx_readv = 1;
-           break;
-       case 'w':
-           rxwrite_size = strtol(optarg, &ptr, 0);
-           if (ptr != 0 && ptr[0] != '\0')
-               errx(1, "can't resolve writesize");
-           if (rxwrite_size > sizeof(somebuf))
-               errx(1, "%d > sizeof(somebuf) (%"AFS_SIZET_FMT")", rxwrite_size,
-                    sizeof(somebuf));
-           break;
-       case 'W':
-           maxwsize = strtol(optarg, &ptr, 0);
-           if (ptr && *ptr != '\0')
-               errx(1, "can't resolve max send/recv window size (packets)");
-           break;
-       case 'T':
-           times = strtol(optarg, &ptr, 0);
-           if (ptr && *ptr != '\0')
-               errx(1, "can't resolve number of times to execute rpc");
-           break;
-       case 'S':
-           sendbytes = strtol(optarg, &ptr, 0);
-           if (ptr && *ptr != '\0')
-               errx(1, "can't resolve number of bytes to send");
-           break;
-       case 'R':
-           readbytes = strtol(optarg, &ptr, 0);
-           if (ptr && *ptr != '\0')
-               errx(1, "can't resolve number of bytes to receive");
-           break;
-       case 't':
-#ifdef AFS_PTHREAD_ENV
-           threads = strtol(optarg, &ptr, 0);
-           if (ptr && *ptr != '\0')
-               errx(1, "can't resolve number of threads to execute");
-            if (threads > MAX_THREADS)
-               errx(1, "too many threads");
-#else
-            errx(1, "Not built for pthreads");
-#endif
-           break;
-       case 'f':
-           filename = optarg;
-           break;
-       case 'D':
-           dumpstats = 1;
-           break;
-       case 'N':
-           nostats = 1;
-           break;
-       case 'H':
-           hotthreads = 1;
-           break;
-       case 'j':
-         nojumbo=1;
-         break;
-       case 'm':
-         maxmtu = strtol(optarg, &ptr, 0);
-         if (ptr && *ptr != '\0')
-           errx(1, "can't resolve rx maxmtu to use");
-           break;
-       case 'u':
-           udpbufsz = strtol(optarg, &ptr, 0) * 1024;
-           if (ptr && *ptr != '\0')
-               errx(1, "can't resolve upd buffer size (Kbytes)");
-           break;
-       case '4':
-         RX_IPUDP_SIZE = 28;
-         break;
-       default:
-           usage();
-       }
-    }
-
-    if (nostats && dumpstats)
-        errx(1, "cannot set both -N and -D");
-
-    if (threads > 1 && cmd == RX_PERF_FILE)
-        errx(1, "cannot use multiple threads with file command");
-
-    if (optind != argc)
-       usage();
-
-    if (cmd == RX_PERF_UNKNOWN)
-       errx(1, "no command given to the client");
-
-    do_client(host, port, filename, cmd, times, bytes, sendbytes,
-             readbytes, dumpstats, nojumbo, maxmtu, maxwsize, minpeertimeout,
-              udpbufsz, nostats, hotthreads, threads);
-
-    return 0;
-}
-
-/*
- * setup world and call cmd
- */
-
-int
-main(int argc, char **argv)
-{
-#ifndef AFS_PTHREAD_ENV
-    PROCESS pid;
-#endif
-
-    __progname = strrchr(argv[0], '/');
-    if (__progname == 0)
-       __progname = argv[0];
-
-#ifndef AFS_NT40_ENV
-    signal(SIGUSR1, sigusr1);
-    signal(SIGINT, sigint);
-#endif
-
-#ifndef AFS_PTHREAD_ENV
-    LWP_InitializeProcessSupport(LWP_NORMAL_PRIORITY, &pid);
-#endif
-
-    memset(somebuf, 0, sizeof(somebuf));
-
-    if (argc >= 2 && strcmp(argv[1], "server") == 0)
-       rxperf_server(argc - 1, argv + 1);
-    else if (argc >= 2 && strcmp(argv[1], "client") == 0)
-       rxperf_client(argc - 1, argv + 1);
-    else
-       usage();
-    return 0;
-}
diff --git a/src/rx/test/rxperf.rc b/src/rx/test/rxperf.rc
deleted file mode 100644 (file)
index ea52ab8..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright 2000, International Business Machines Corporation and others.
- * All Rights Reserved.
- * 
- * This software has been released under the terms of the IBM Public
- * License.  For details, see the LICENSE file in the top-level source
- * directory or online at http://www.openafs.org/dl/license10.html
- */
-
-/* Define VERSIONINFO resource */
-
-#define  AFS_VERINFO_FILE_DESCRIPTION "RX Performance Test (pthread)"
-#define AFS_VERINFO_NAME "rxperf"
-#define AFS_VERINFO_FILENAME "rxperf.exe"
-
-#include "AFS_component_version_number.h"
-#include "..\..\config\NTVersioninfo.rc"
index d61a947c3e2c887a70eb4e3dfec6ca18db6c9e73..45da45a1da1f8ce6085300e39c289438821bcd77 100644 (file)
@@ -1,6 +1,6 @@
 srcdir=@srcdir@
 
-SUBDIRS=dumpscan
+SUBDIRS=dumpscan rxperf
 
 all dest install clean distclean:
        @for A in $(SUBDIRS); do cd $$A && $(MAKE) $@ && cd .. || exit 1; done
diff --git a/src/tools/rxperf/.gitignore b/src/tools/rxperf/.gitignore
new file mode 100644 (file)
index 0000000..5a2f465
--- /dev/null
@@ -0,0 +1,5 @@
+# After changing this file, please run
+#     git ls-files -i --exclude-standard
+# to check that you haven't inadvertently ignored any tracked files.
+
+/rxperf
diff --git a/src/tools/rxperf/Makefile.in b/src/tools/rxperf/Makefile.in
new file mode 100644 (file)
index 0000000..ca99430
--- /dev/null
@@ -0,0 +1,20 @@
+srcdir=@srcdir@
+
+include @TOP_OBJDIR@/src/config/Makefile.config
+include @TOP_OBJDIR@/src/config/Makefile.pthread
+
+LIBS= $(TOP_LIBDIR)/libafsrpc.a \
+      $(TOP_LIBDIR)/libopr.a
+
+all: rxperf
+
+rxperf: rxperf.o $(LIBS)
+       $(AFS_LDRULE) rxperf.o $(LIBS) $(LIB_hcrypto) $(LIB_roken) \
+               $(MT_LIBS) $(XLIBS)
+
+install:
+
+dest:
+
+clean:
+       $(RM) -f rxperf.o rxperf
diff --git a/src/tools/rxperf/NTMakefile b/src/tools/rxperf/NTMakefile
new file mode 100644 (file)
index 0000000..3f79180
--- /dev/null
@@ -0,0 +1,41 @@
+# Copyright 2000, International Business Machines Corporation and others.
+# All Rights Reserved.
+# 
+# This software has been released under the terms of the IBM Public
+# License.  For details, see the LICENSE file in the top-level source
+# directory or online at http://www.openafs.org/dl/license10.html
+
+AFSDEV_AUXCDEFINES = -DAFS_PTHREAD_ENV -DHAVE_WARNX -DHAVE_ERRX -DHAVE_WARN -DHAVE_ERR
+!IF ("$(AFSDEV_BUILDTYPE)" == "CHECKED")
+AFSDEV_AUXCDEFINES = $(AFSDEV_AUXCDEFINES) -DRXDEBUG
+!ENDIF
+
+RELDIR=tools/rxperf
+!INCLUDE ..\..\config\NTMakefile.$(SYS_NAME)
+!INCLUDE ..\..\config\NTMakefile.version
+
+LIBS = \
+       $(DESTDIR)\lib\afs\afsreg.lib \
+       $(DESTDIR)\lib\afs\mtafsutil.lib \
+       $(DESTDIR)\lib\afsrpc.lib \
+       $(DESTDIR)\lib\afspthread.lib \
+        $(DESTDIR)\lib\afsroken.lib \
+       $(DESTDIR)\lib\opr.lib
+
+
+all: $(OUT)\rxperf.exe
+
+$(OUT)\rxperf.res: rxperf.rc AFS_component_version_number.h
+
+$(OUT)\rxperf.exe: $(OUT)\rxperf.obj $(OUT)\rxperf.res $(LIBS)
+       $(EXECONLINK)
+        $(_VC_MANIFEST_EMBED_EXE)
+        $(CODESIGN_USERLAND)
+        $(SYMSTORE_IMPORT)
+
+mkdir:
+       
+install: all
+
+clean::
+    $(DEL) $(OUT)\rxperf.res
diff --git a/src/tools/rxperf/rxperf.c b/src/tools/rxperf/rxperf.c
new file mode 100644 (file)
index 0000000..3367fd2
--- /dev/null
@@ -0,0 +1,1150 @@
+/*
+ * Copyright (c) 2000 - 2001 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * 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
+ *    at such time that OpenAFS documentation is written.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 THE INSTITUTE OR CONTRIBUTORS 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 <afsconfig.h>
+
+/*
+nn * We are using getopt since we want it to be possible to link to
+ * transarc libs.
+ */
+
+#include <afsconfig.h>
+#include <afs/param.h>
+#include <roken.h>
+
+#ifdef HAVE_SYS_FILE_H
+#include <sys/file.h>
+#endif
+
+#include <assert.h>
+
+#include <rx/rx.h>
+#include <rx/rx_null.h>
+#include <rx/rx_globals.h>
+#include <rx/rx_packet.h>
+
+#ifdef AFS_PTHREAD_ENV
+#include <pthread.h>
+#define MAX_THREADS 128
+#endif
+
+#define DEFAULT_PORT 7009      /* To match tcpdump */
+#define DEFAULT_HOST "127.0.0.1"
+#define DEFAULT_BYTES 1024 * 1024
+#define RXPERF_BUFSIZE 512 * 1024
+
+enum { RX_PERF_VERSION = 3 };
+enum { RX_SERVER_ID = 147 };
+enum { RX_PERF_UNKNOWN = -1,
+       RX_PERF_SEND = 0,
+       RX_PERF_RECV = 1,
+       RX_PERF_RPC = 3,
+       RX_PERF_FILE = 4
+};
+
+enum { RXPERF_MAGIC_COOKIE = 0x4711 };
+
+/*
+ *
+ */
+
+#if RXPERF_DEBUG
+#define DBFPRINT(x) do { printf x ; } while(0)
+#else
+#define DBFPRINT(x)
+#endif
+
+static void
+sigusr1(int foo)
+{
+    exit(2);                   /* XXX profiler */
+}
+
+static void
+sigint(int foo)
+{
+    rx_Finalize();
+    exit(2);                   /* XXX profiler */
+}
+
+/*
+ *
+ */
+
+static struct timeval timer_start;
+static struct timeval timer_stop;
+static int timer_check = 0;
+
+static void
+start_timer(void)
+{
+    timer_check++;
+    gettimeofday(&timer_start, NULL);
+}
+
+/*
+ *
+ */
+
+static void
+end_and_print_timer(char *str)
+{
+    long long start_l, stop_l;
+
+    timer_check--;
+    assert(timer_check == 0);
+    gettimeofday(&timer_stop, NULL);
+    start_l = timer_start.tv_sec * 1000000 + timer_start.tv_usec;
+    stop_l = timer_stop.tv_sec * 1000000 + timer_stop.tv_usec;
+    printf("%s:\t%8llu msec\n", str, (stop_l - start_l) / 1000);
+}
+
+/*
+ *
+ */
+
+static u_long
+str2addr(const char *s)
+{
+    struct in_addr server;
+    struct hostent *h;
+
+#ifndef INADDR_NONE
+#define INADDR_NONE 0xffffffff
+#endif
+    if (inet_addr(s) != INADDR_NONE)
+       return inet_addr(s);
+    h = gethostbyname(s);
+    if (h != NULL) {
+       memcpy(&server, h->h_addr_list[0], sizeof(server));
+       return server.s_addr;
+    }
+    return 0;
+}
+
+
+/*
+ *
+ */
+
+static void
+get_sec(int serverp, struct rx_securityClass **sec, int *secureindex)
+{
+    if (serverp) {
+       *sec = rxnull_NewServerSecurityObject();
+       *secureindex = 1;
+    } else {
+       *sec = rxnull_NewClientSecurityObject();
+       *secureindex = 0;
+    }
+}
+
+/*
+ * process the "RPC" and return the results
+ */
+
+char somebuf[RXPERF_BUFSIZE];
+
+afs_int32 rxwrite_size = sizeof(somebuf);
+afs_int32 rxread_size = sizeof(somebuf);
+afs_int32 use_rx_readv = 0;
+
+static int
+do_readbytes(struct rx_call *call, afs_int32 bytes)
+{
+    struct iovec tiov[RX_MAXIOVECS];
+    afs_int32 size;
+    int tnio;
+    int code;
+
+    while (bytes > 0) {
+       size = rxread_size;
+
+       if (size > bytes)
+           size = bytes;
+       if (use_rx_readv) {
+            if (size > RX_MAX_PACKET_DATA_SIZE)
+                size = RX_MAX_PACKET_DATA_SIZE;
+            code = rx_Readv(call, tiov, &tnio, RX_MAXIOVECS, size);
+        } else
+            code = rx_Read(call, somebuf, size);
+        if (code != size)
+            return 1;
+
+       bytes -= size;
+    }
+    return 0;
+}
+
+static int
+do_sendbytes(struct rx_call *call, afs_int32 bytes)
+{
+    afs_int32 size;
+
+    while (bytes > 0) {
+       size = rxwrite_size;
+       if (size > bytes)
+           size = bytes;
+       if (rx_Write(call, somebuf, size) != size)
+           return 1;
+       bytes -= size;
+    }
+    return 0;
+}
+
+
+static afs_int32
+rxperf_ExecuteRequest(struct rx_call *call)
+{
+    afs_int32 version;
+    afs_int32 command;
+    afs_int32 bytes;
+    afs_int32 recvb;
+    afs_int32 sendb;
+    afs_int32 data;
+    afs_uint32 num;
+    afs_uint32 *readwrite;
+    afs_uint32 i;
+    int readp = TRUE;
+
+    DBFPRINT(("got a request\n"));
+
+    if (rx_Read32(call, &version) != 4) {
+       warn("rx_Read failed to read version");
+       return -1;
+    }
+
+    if (htonl(RX_PERF_VERSION) != version) {
+       warnx("client has wrong version");
+       return -1;
+    }
+
+    if (rx_Read32(call, &command) != 4) {
+       warnx("rx_Read failed to read command");
+       return -1;
+    }
+    command = ntohl(command);
+
+    if (rx_Read32(call, &data) != 4) {
+       warnx("rx_Read failed to read size");
+       return -1;
+    }
+    rxread_size = ntohl(data);
+    if (rxread_size > sizeof(somebuf)) {
+       warnx("rxread_size too large %d", rxread_size);
+       return -1;
+    }
+
+    if (rx_Read32(call, &data) != 4) {
+       warnx("rx_Read failed to write size");
+       return -1;
+    }
+    rxwrite_size = ntohl(data);
+    if (rxwrite_size > sizeof(somebuf)) {
+       warnx("rxwrite_size too large %d", rxwrite_size);
+       return -1;
+    }
+
+    switch (command) {
+    case RX_PERF_SEND:
+       DBFPRINT(("got a send request\n"));
+
+       if (rx_Read32(call, &bytes) != 4) {
+           warnx("rx_Read failed to read bytes");
+           return -1;
+       }
+       bytes = ntohl(bytes);
+
+       DBFPRINT(("reading(%d) ", bytes));
+       do_readbytes(call, bytes);
+
+       data = htonl(RXPERF_MAGIC_COOKIE);
+       if (rx_Write32(call, &data) != 4) {
+           warnx("rx_Write failed when sending back result");
+           return -1;
+       }
+       DBFPRINT(("done\n"));
+
+       break;
+    case RX_PERF_RPC:
+       DBFPRINT(("got a rpc request, reading commands\n"));
+
+       if (rx_Read32(call, &recvb) != 4) {
+           warnx("rx_Read failed to read recvbytes");
+           return -1;
+       }
+       recvb = ntohl(recvb);
+       if (rx_Read32(call, &sendb) != 4) {
+           warnx("rx_Read failed to read sendbytes");
+           return -1;
+       }
+       sendb = ntohl(sendb);
+
+       DBFPRINT(("read(%d) ", recvb));
+       if (do_readbytes(call, recvb)) {
+           warnx("do_readbytes failed");
+           return -1;
+       }
+       DBFPRINT(("send(%d) ", sendb));
+       if (do_sendbytes(call, sendb)) {
+           warnx("sendbytes failed");
+           return -1;
+       }
+
+       DBFPRINT(("done\n"));
+
+       data = htonl(RXPERF_MAGIC_COOKIE);
+       if (rx_Write32(call, &data) != 4) {
+           warnx("rx_Write failed when sending back magic cookie");
+           return -1;
+       }
+
+       break;
+    case RX_PERF_FILE:
+       if (rx_Read32(call, &data) != 4)
+           errx(1, "failed to read num from client");
+       num = ntohl(data);
+
+       readwrite = malloc(num * sizeof(afs_uint32));
+       if (readwrite == NULL)
+           err(1, "malloc");
+
+       if (rx_Read(call, (char*)readwrite, num * sizeof(afs_uint32)) !=
+           num * sizeof(afs_uint32))
+           errx(1, "failed to read recvlist from client");
+
+       for (i = 0; i < num; i++) {
+           if (readwrite[i] == 0) {
+               DBFPRINT(("readp %d", readwrite[i]));
+               readp = !readp;
+           }
+
+           bytes = ntohl(readwrite[i]) * sizeof(afs_uint32);
+
+           if (readp) {
+               DBFPRINT(("read\n"));
+               do_readbytes(call, bytes);
+           } else {
+               do_sendbytes(call, bytes);
+               DBFPRINT(("send\n"));
+           }
+       }
+
+       break;
+    case RX_PERF_RECV:
+       DBFPRINT(("got a recv request\n"));
+
+       if (rx_Read32(call, &bytes) != 4) {
+           warnx("rx_Read failed to read bytes");
+           return -1;
+       }
+       bytes = ntohl(bytes);
+
+       DBFPRINT(("sending(%d) ", bytes));
+       do_sendbytes(call, bytes);
+
+       data = htonl(RXPERF_MAGIC_COOKIE);
+       if (rx_Write32(call, &data) != 4) {
+           warnx("rx_Write failed when sending back result");
+           return -1;
+       }
+       DBFPRINT(("done\n"));
+
+       break;
+    default:
+       warnx("client sent a unsupported command");
+       return -1;
+    }
+    DBFPRINT(("done with command\n"));
+
+    return 0;
+}
+
+/*
+ *
+ */
+
+static void
+do_server(short port, int nojumbo, int maxmtu, int maxwsize, int minpeertimeout,
+          int udpbufsz, int nostats, int hotthread,
+          int minprocs, int maxprocs)
+{
+    struct rx_service *service;
+    struct rx_securityClass *secureobj;
+    int secureindex;
+    int ret;
+
+#ifdef AFS_NT40_ENV
+    if (afs_winsockInit() < 0) {
+       printf("Can't initialize winsock.\n");
+       exit(1);
+    }
+#endif
+
+    if (hotthread)
+        rx_EnableHotThread();
+
+    if (nostats)
+        rx_enable_stats = 0;
+
+    rx_SetUdpBufSize(udpbufsz);
+
+    ret = rx_Init(htons(port));
+    if (ret)
+       errx(1, "rx_Init failed");
+
+    if (nojumbo)
+      rx_SetNoJumbo();
+
+    if (maxmtu)
+      rx_SetMaxMTU(maxmtu);
+
+    if (maxwsize) {
+        rx_SetMaxReceiveWindow(maxwsize);
+        rx_SetMaxSendWindow(maxwsize);
+    }
+
+    if (minpeertimeout)
+        rx_SetMinPeerTimeout(minpeertimeout);
+
+
+    get_sec(1, &secureobj, &secureindex);
+
+    service =
+       rx_NewService(0, RX_SERVER_ID, "rxperf", &secureobj, secureindex,
+                     rxperf_ExecuteRequest);
+    if (service == NULL)
+       errx(1, "Cant create server");
+
+    rx_SetMinProcs(service, minprocs);
+    rx_SetMaxProcs(service, maxprocs);
+
+    rx_SetCheckReach(service, 1);
+
+    rx_StartServer(1);
+
+    abort();
+}
+
+/*
+ *
+ */
+
+static void
+readfile(const char *filename, afs_uint32 ** readwrite, afs_uint32 * size)
+{
+    FILE *f;
+    afs_uint32 len = 16;
+    afs_uint32 num = 0;
+    afs_uint32 data;
+    char *ptr;
+    char *buf;
+
+    *readwrite = malloc(sizeof(afs_uint32) * len);
+    buf = malloc(RXPERF_BUFSIZE);
+
+    if (*readwrite == NULL)
+       err(1, "malloc");
+
+    f = fopen(filename, "r");
+    if (f == NULL)
+       err(1, "fopen");
+
+    while (fgets(buf, sizeof(buf), f) != NULL) {
+       if (num >= len) {
+           len = len * 2;
+           *readwrite = realloc(*readwrite, len * sizeof(afs_uint32));
+           if (*readwrite == NULL)
+               err(1, "realloc");
+       }
+
+       if (*buf != '\n') {
+           data = htonl(strtol(buf, &ptr, 0));
+           if (ptr && ptr == buf)
+               errx(1, "can't resolve number of bytes to transfer");
+       } else {
+           data = 0;
+       }
+
+       (*readwrite)[num] = data;
+       num++;
+    }
+
+    *size = num;
+
+
+    if (fclose(f) == -1)
+       err(1, "fclose");
+    free(buf);
+}
+
+struct client_data {
+    struct rx_connection *conn;
+    char *filename;
+    int command;
+    afs_int32 times;
+    afs_int32 bytes;
+    afs_int32 sendbytes;
+    afs_int32 readbytes;
+};
+
+static void *
+client_thread( void *vparams)
+{
+    struct client_data *params = (struct client_data *)vparams;
+    struct rx_call *call;
+    afs_int32 data;
+    int i, j;
+    afs_uint32 *readwrite;
+    int readp = FALSE;
+    afs_uint32 size;
+    afs_uint32 num;
+
+    for (i = 0; i < params->times; i++) {
+
+       DBFPRINT(("starting command "));
+
+       call = rx_NewCall(params->conn);
+       if (call == NULL)
+           errx(1, "rx_NewCall failed");
+
+       data = htonl(RX_PERF_VERSION);
+       if (rx_Write32(call, &data) != 4)
+           errx(1, "rx_Write failed to send version (err %d)", rx_Error(call));
+
+       data = htonl(params->command);
+       if (rx_Write32(call, &data) != 4)
+           errx(1, "rx_Write failed to send command (err %d)", rx_Error(call));
+
+       data = htonl(rxread_size);
+       if (rx_Write32(call, &data) != 4)
+           errx(1, "rx_Write failed to send read size (err %d)", rx_Error(call));
+       data = htonl(rxwrite_size);
+       if (rx_Write32(call, &data) != 4)
+           errx(1, "rx_Write failed to send write read (err %d)", rx_Error(call));
+
+
+       switch (params->command) {
+       case RX_PERF_RECV:
+           DBFPRINT(("command "));
+
+           data = htonl(params->bytes);
+           if (rx_Write32(call, &data) != 4)
+               errx(1, "rx_Write failed to send size (err %d)", rx_Error(call));
+
+           DBFPRINT(("sending(%d) ", params->bytes));
+           if (do_readbytes(call, params->bytes))
+               errx(1, "sendbytes (err %d)", rx_Error(call));
+
+           if (rx_Read32(call, &data) != 4)
+               errx(1, "failed to read result from server (err %d)", rx_Error(call));
+
+           if (data != htonl(RXPERF_MAGIC_COOKIE))
+               warn("server send wrong magic cookie in responce");
+
+           DBFPRINT(("done\n"));
+
+           break;
+       case RX_PERF_SEND:
+           DBFPRINT(("command "));
+
+           data = htonl(params->bytes);
+           if (rx_Write32(call, &data) != 4)
+               errx(1, "rx_Write failed to send size (err %d)", rx_Error(call));
+
+           DBFPRINT(("sending(%d) ", params->bytes));
+           if (do_sendbytes(call, params->bytes))
+               errx(1, "sendbytes (err %d)", rx_Error(call));
+
+           if (rx_Read32(call, &data) != 4)
+               errx(1, "failed to read result from server (err %d)", rx_Error(call));
+
+           if (data != htonl(RXPERF_MAGIC_COOKIE))
+               warn("server send wrong magic cookie in responce");
+
+           DBFPRINT(("done\n"));
+
+           break;
+       case RX_PERF_RPC:
+           DBFPRINT(("commands "));
+
+           data = htonl(params->sendbytes);
+           if (rx_Write32(call, &data) != 4)
+               errx(1, "rx_Write failed to send command (err %d)", rx_Error(call));
+
+           data = htonl(params->readbytes);
+           if (rx_Write32(call, &data) != 4)
+               errx(1, "rx_Write failed to send command (err %d)", rx_Error(call));
+
+           DBFPRINT(("send(%d) ", params->sendbytes));
+           if (do_sendbytes(call, params->sendbytes))
+               errx(1, "sendbytes (err %d)", rx_Error(call));
+
+           DBFPRINT(("recv(%d) ", params->readbytes));
+           if (do_readbytes(call, params->readbytes))
+               errx(1, "sendbytes (err %d)", rx_Error(call));
+
+           if (rx_Read32(call, &data) != 4)
+               errx(1, "failed to read result from server (err %d)", rx_Error(call));
+
+           if (data != htonl(RXPERF_MAGIC_COOKIE))
+               warn("server send wrong magic cookie in responce");
+
+           DBFPRINT(("done\n"));
+
+           break;
+
+       case RX_PERF_FILE:
+           readfile(params->filename, &readwrite, &num);
+
+           data = htonl(num);
+           if (rx_Write32(call, &data) != 4)
+               errx(1, "rx_Write failed to send size (err %d)", rx_Error(call));
+
+           if (rx_Write(call, (char *)readwrite, num * sizeof(afs_uint32))
+               != num * sizeof(afs_uint32))
+               errx(1, "rx_Write failed to send list (err %d)", rx_Error(call));
+
+           for (j = 0; j < num; j++) {
+               if (readwrite[j] == 0)
+                   readp = !readp;
+
+               size = ntohl(readwrite[j]) * sizeof(afs_uint32);
+
+               if (readp) {
+                   if (do_readbytes(call, size))
+                       errx(1, "sendbytes (err %d)", rx_Error(call));
+                   DBFPRINT(("read\n"));
+               } else {
+                   if (do_sendbytes(call, size))
+                       errx(1, "sendbytes (err %d)", rx_Error(call));
+                   DBFPRINT(("send\n"));
+               }
+           }
+           break;
+       default:
+           abort();
+       }
+
+       rx_EndCall(call, 0);
+    }
+
+#ifdef AFS_PTHREAD_ENV
+    pthread_exit(NULL);
+#endif
+
+    return NULL;
+}
+
+/*
+ *
+ */
+
+static void
+do_client(const char *server, short port, char *filename, afs_int32 command,
+         afs_int32 times, afs_int32 bytes, afs_int32 sendbytes, afs_int32 readbytes,
+          int dumpstats, int nojumbo, int maxmtu, int maxwsize, int minpeertimeout,
+          int udpbufsz, int nostats, int hotthread, int threads)
+{
+    struct rx_connection *conn;
+    afs_uint32 addr;
+    struct rx_securityClass *secureobj;
+    int secureindex;
+    int ret;
+    char stamp[2048];
+    struct client_data *params;
+
+#ifdef AFS_PTHREAD_ENV
+    int i;
+    pthread_t thread[MAX_THREADS];
+    pthread_attr_t tattr;
+    void *status;
+#endif
+
+    params = malloc(sizeof(struct client_data));
+    memset(params, 0, sizeof(struct client_data));
+
+#ifdef AFS_NT40_ENV
+    if (afs_winsockInit() < 0) {
+       printf("Can't initialize winsock.\n");
+       exit(1);
+    }
+#endif
+
+    if (hotthread)
+        rx_EnableHotThread();
+
+    if (nostats)
+        rx_enable_stats = 0;
+
+    addr = str2addr(server);
+
+    rx_SetUdpBufSize(udpbufsz);
+
+    ret = rx_Init(0);
+    if (ret)
+       errx(1, "rx_Init failed");
+
+    if (nojumbo)
+      rx_SetNoJumbo();
+
+    if (maxmtu)
+      rx_SetMaxMTU(maxmtu);
+
+    if (maxwsize) {
+        rx_SetMaxReceiveWindow(maxwsize);
+        rx_SetMaxSendWindow(maxwsize);
+    }
+
+    if (minpeertimeout)
+        rx_SetMinPeerTimeout(minpeertimeout);
+
+
+    get_sec(0, &secureobj, &secureindex);
+
+    switch (command) {
+    case RX_PERF_RPC:
+        sprintf(stamp, "RPC: threads\t%d, times\t%d, write bytes\t%d, read bytes\t%d",
+                 threads, times, sendbytes, readbytes);
+        break;
+    case RX_PERF_RECV:
+        sprintf(stamp, "RECV: threads\t%d, times\t%d, bytes\t%d",
+                 threads, times, bytes);
+        break;
+    case RX_PERF_SEND:
+        sprintf(stamp, "SEND: threads\t%d, times\t%d, bytes\t%d",
+                 threads, times, bytes);
+        break;
+    case RX_PERF_FILE:
+        sprintf(stamp, "FILE %s: threads\t%d, times\t%d, bytes\t%d",
+                 filename, threads, times, bytes);
+        break;
+    }
+
+    conn = rx_NewConnection(addr, htons(port), RX_SERVER_ID, secureobj, secureindex);
+    if (conn == NULL)
+       errx(1, "failed to contact server");
+
+#ifdef AFS_PTHREAD_ENV
+    pthread_attr_init(&tattr);
+    pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_JOINABLE);
+#endif
+
+    params->conn = conn;
+    params->filename = filename;
+    params->command = command;
+    params->times = times;
+    params->bytes = bytes;
+    params->sendbytes = sendbytes;
+    params->readbytes = readbytes;
+
+    start_timer();
+
+#ifdef AFS_PTHREAD_ENV
+    for ( i=0; i<threads; i++) {
+        pthread_create(&thread[i], &tattr, client_thread, params);
+        if ( (i + 1) % RX_MAXCALLS == 0 ) {
+            conn = rx_NewConnection(addr, htons(port), RX_SERVER_ID, secureobj, secureindex);
+            if (conn != NULL) {
+                struct client_data *new_params = malloc(sizeof(struct client_data));
+                memcpy(new_params, params, sizeof(struct client_data));
+                new_params->conn = conn;
+                params = new_params;
+            }
+        }
+    }
+#else
+        client_thread(params);
+#endif
+
+#ifdef AFS_PTHREAD_ENV
+    for ( i=0; i<threads; i++)
+        pthread_join(thread[i], &status);
+#endif
+
+    end_and_print_timer(stamp);
+    DBFPRINT(("done for good\n"));
+
+    if (dumpstats) {
+       rx_PrintStats(stdout);
+       rx_PrintPeerStats(stdout, rx_PeerOf(conn));
+    }
+    rx_Finalize();
+
+#ifdef AFS_PTHREAD_ENV
+    pthread_attr_destroy(&tattr);
+#endif
+
+    free(params);
+}
+
+static void
+usage(void)
+{
+#define COMMON ""
+
+    fprintf(stderr, "usage: %s client -c send -b <bytes>\n", getprogname());
+    fprintf(stderr, "usage: %s client -c recv -b <bytes>\n", getprogname());
+    fprintf(stderr,
+           "usage: %s client -c rpc  -S <sendbytes> -R <recvbytes>\n",
+           getprogname());
+    fprintf(stderr, "usage: %s client -c file -f filename\n", getprogname());
+    fprintf(stderr,
+           "%s: usage: common option to the client "
+           "-w <write-bytes> -r <read-bytes> -T times -p port -s server -D\n",
+           getprogname());
+    fprintf(stderr, "usage: %s server -p port\n", getprogname());
+#undef COMMMON
+    exit(1);
+}
+
+
+
+/*
+ * do argument processing and call networking functions
+ */
+
+static int
+rxperf_server(int argc, char **argv)
+{
+    short port = DEFAULT_PORT;
+    int nojumbo = 0;
+    int maxmtu = 0;
+    int nostats = 0;
+    int udpbufsz = 64 * 1024;
+    int hotthreads = 0;
+    int minprocs = 2;
+    int maxprocs = 20;
+    int maxwsize = 0;
+    int minpeertimeout = 0;
+    char *ptr;
+    int ch;
+
+    while ((ch = getopt(argc, argv, "r:d:p:P:w:W:HNjm:u:4:s:S:V")) != -1) {
+       switch (ch) {
+       case 'd':
+#ifdef RXDEBUG
+           rx_debugFile = fopen(optarg, "w");
+           if (rx_debugFile == NULL)
+               err(1, "fopen %s", optarg);
+#else
+           errx(1, "compiled without RXDEBUG");
+#endif
+           break;
+       case 'r':
+           rxread_size = strtol(optarg, &ptr, 0);
+           if (ptr != 0 && ptr[0] != '\0')
+               errx(1, "can't resolve readsize");
+           if (rxread_size > sizeof(somebuf))
+               errx(1, "%d > sizeof(somebuf) (%"AFS_SIZET_FMT")", rxread_size,
+                    sizeof(somebuf));
+           break;
+       case 's':
+           minprocs = strtol(optarg, &ptr, 0);
+           if (ptr != 0 && ptr[0] != '\0')
+               errx(1, "can't resolve minprocs");
+           break;
+       case 'S':
+           maxprocs = strtol(optarg, &ptr, 0);
+           if (ptr != 0 && ptr[0] != '\0')
+               errx(1, "can't resolve maxprocs");
+           break;
+       case 'P':
+           minpeertimeout = strtol(optarg, &ptr, 0);
+           if (ptr != 0 && ptr[0] != '\0')
+               errx(1, "can't resolve min peer timeout");
+           break;
+       case 'p':
+           port = (short) strtol(optarg, &ptr, 0);
+           if (ptr != 0 && ptr[0] != '\0')
+               errx(1, "can't resolve portname");
+           break;
+       case 'w':
+           rxwrite_size = strtol(optarg, &ptr, 0);
+           if (ptr != 0 && ptr[0] != '\0')
+               errx(1, "can't resolve writesize");
+           if (rxwrite_size > sizeof(somebuf))
+               errx(1, "%d > sizeof(somebuf) (%"AFS_SIZET_FMT")", rxwrite_size,
+                    sizeof(somebuf));
+           break;
+       case 'j':
+         nojumbo=1;
+         break;
+       case 'N':
+         nostats=1;
+         break;
+       case 'H':
+           hotthreads = 1;
+           break;
+       case 'm':
+         maxmtu = strtol(optarg, &ptr, 0);
+         if (ptr && *ptr != '\0')
+           errx(1, "can't resolve rx maxmtu to use");
+           break;
+       case 'u':
+           udpbufsz = strtol(optarg, &ptr, 0) * 1024;
+           if (ptr && *ptr != '\0')
+               errx(1, "can't resolve upd buffer size (Kbytes)");
+           break;
+       case 'V':
+           use_rx_readv = 1;
+           break;
+       case 'W':
+           maxwsize = strtol(optarg, &ptr, 0);
+           if (ptr && *ptr != '\0')
+               errx(1, "can't resolve max send/recv window size (packets)");
+           break;
+       case '4':
+         RX_IPUDP_SIZE = 28;
+         break;
+       default:
+           usage();
+       }
+    }
+
+    if (optind != argc)
+       usage();
+
+    do_server(port, nojumbo, maxmtu, maxwsize, minpeertimeout, udpbufsz,
+              nostats, hotthreads, minprocs, maxprocs);
+
+    return 0;
+}
+
+/*
+ * do argument processing and call networking functions
+ */
+
+static int
+rxperf_client(int argc, char **argv)
+{
+    char *host = DEFAULT_HOST;
+    int bytes = DEFAULT_BYTES;
+    short port = DEFAULT_PORT;
+    char *filename = NULL;
+    afs_int32 cmd;
+    int sendbytes = 3;
+    int readbytes = 30;
+    int times = 100;
+    int dumpstats = 0;
+    int nojumbo = 0;
+    int nostats = 0;
+    int maxmtu = 0;
+    int hotthreads = 0;
+    int threads = 1;
+    int udpbufsz = 64 * 1024;
+    int maxwsize = 0;
+    int minpeertimeout = 0;
+    char *ptr;
+    int ch;
+
+    cmd = RX_PERF_UNKNOWN;
+
+    while ((ch = getopt(argc, argv, "T:S:R:b:c:d:p:P:r:s:w:W:f:HDNjm:u:4:t:V")) != -1) {
+       switch (ch) {
+       case 'b':
+           bytes = strtol(optarg, &ptr, 0);
+           if (ptr && *ptr != '\0')
+               errx(1, "can't resolve number of bytes to transfer");
+           break;
+       case 'c':
+           if (strcasecmp(optarg, "send") == 0)
+               cmd = RX_PERF_SEND;
+           else if (strcasecmp(optarg, "recv") == 0)
+               cmd = RX_PERF_RECV;
+           else if (strcasecmp(optarg, "rpc") == 0)
+               cmd = RX_PERF_RPC;
+           else if (strcasecmp(optarg, "file") == 0)
+               cmd = RX_PERF_FILE;
+           else
+               errx(1, "unknown command %s", optarg);
+           break;
+       case 'd':
+#ifdef RXDEBUG
+           rx_debugFile = fopen(optarg, "w");
+           if (rx_debugFile == NULL)
+               err(1, "fopen %s", optarg);
+#else
+           errx(1, "compiled without RXDEBUG");
+#endif
+           break;
+       case 'P':
+           minpeertimeout = strtol(optarg, &ptr, 0);
+           if (ptr != 0 && ptr[0] != '\0')
+               errx(1, "can't resolve min peer timeout");
+           break;
+       case 'p':
+           port = (short) strtol(optarg, &ptr, 0);
+           if (ptr != 0 && ptr[0] != '\0')
+               errx(1, "can't resolve portname");
+           break;
+       case 'r':
+           rxread_size = strtol(optarg, &ptr, 0);
+           if (ptr != 0 && ptr[0] != '\0')
+               errx(1, "can't resolve readsize");
+           if (rxread_size > sizeof(somebuf))
+               errx(1, "%d > sizeof(somebuf) (%"AFS_SIZET_FMT")", rxread_size,
+                    sizeof(somebuf));
+           break;
+       case 's':
+           host = strdup(optarg);
+           if (host == NULL)
+               err(1, "strdup");
+           break;
+       case 'V':
+           use_rx_readv = 1;
+           break;
+       case 'w':
+           rxwrite_size = strtol(optarg, &ptr, 0);
+           if (ptr != 0 && ptr[0] != '\0')
+               errx(1, "can't resolve writesize");
+           if (rxwrite_size > sizeof(somebuf))
+               errx(1, "%d > sizeof(somebuf) (%"AFS_SIZET_FMT")", rxwrite_size,
+                    sizeof(somebuf));
+           break;
+       case 'W':
+           maxwsize = strtol(optarg, &ptr, 0);
+           if (ptr && *ptr != '\0')
+               errx(1, "can't resolve max send/recv window size (packets)");
+           break;
+       case 'T':
+           times = strtol(optarg, &ptr, 0);
+           if (ptr && *ptr != '\0')
+               errx(1, "can't resolve number of times to execute rpc");
+           break;
+       case 'S':
+           sendbytes = strtol(optarg, &ptr, 0);
+           if (ptr && *ptr != '\0')
+               errx(1, "can't resolve number of bytes to send");
+           break;
+       case 'R':
+           readbytes = strtol(optarg, &ptr, 0);
+           if (ptr && *ptr != '\0')
+               errx(1, "can't resolve number of bytes to receive");
+           break;
+       case 't':
+#ifdef AFS_PTHREAD_ENV
+           threads = strtol(optarg, &ptr, 0);
+           if (ptr && *ptr != '\0')
+               errx(1, "can't resolve number of threads to execute");
+            if (threads > MAX_THREADS)
+               errx(1, "too many threads");
+#else
+            errx(1, "Not built for pthreads");
+#endif
+           break;
+       case 'f':
+           filename = optarg;
+           break;
+       case 'D':
+           dumpstats = 1;
+           break;
+       case 'N':
+           nostats = 1;
+           break;
+       case 'H':
+           hotthreads = 1;
+           break;
+       case 'j':
+         nojumbo=1;
+         break;
+       case 'm':
+         maxmtu = strtol(optarg, &ptr, 0);
+         if (ptr && *ptr != '\0')
+           errx(1, "can't resolve rx maxmtu to use");
+           break;
+       case 'u':
+           udpbufsz = strtol(optarg, &ptr, 0) * 1024;
+           if (ptr && *ptr != '\0')
+               errx(1, "can't resolve upd buffer size (Kbytes)");
+           break;
+       case '4':
+         RX_IPUDP_SIZE = 28;
+         break;
+       default:
+           usage();
+       }
+    }
+
+    if (nostats && dumpstats)
+        errx(1, "cannot set both -N and -D");
+
+    if (threads > 1 && cmd == RX_PERF_FILE)
+        errx(1, "cannot use multiple threads with file command");
+
+    if (optind != argc)
+       usage();
+
+    if (cmd == RX_PERF_UNKNOWN)
+       errx(1, "no command given to the client");
+
+    do_client(host, port, filename, cmd, times, bytes, sendbytes,
+             readbytes, dumpstats, nojumbo, maxmtu, maxwsize, minpeertimeout,
+              udpbufsz, nostats, hotthreads, threads);
+
+    return 0;
+}
+
+/*
+ * setup world and call cmd
+ */
+
+int
+main(int argc, char **argv)
+{
+#ifndef AFS_PTHREAD_ENV
+    PROCESS pid;
+#endif
+
+    setprogname(argv[0]);
+
+#ifndef AFS_NT40_ENV
+    signal(SIGUSR1, sigusr1);
+    signal(SIGINT, sigint);
+#endif
+
+#ifndef AFS_PTHREAD_ENV
+    LWP_InitializeProcessSupport(LWP_NORMAL_PRIORITY, &pid);
+#endif
+
+    memset(somebuf, 0, sizeof(somebuf));
+
+    if (argc >= 2 && strcmp(argv[1], "server") == 0)
+       rxperf_server(argc - 1, argv + 1);
+    else if (argc >= 2 && strcmp(argv[1], "client") == 0)
+       rxperf_client(argc - 1, argv + 1);
+    else
+       usage();
+    return 0;
+}
diff --git a/src/tools/rxperf/rxperf.rc b/src/tools/rxperf/rxperf.rc
new file mode 100644 (file)
index 0000000..ea52ab8
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2000, International Business Machines Corporation and others.
+ * All Rights Reserved.
+ * 
+ * This software has been released under the terms of the IBM Public
+ * License.  For details, see the LICENSE file in the top-level source
+ * directory or online at http://www.openafs.org/dl/license10.html
+ */
+
+/* Define VERSIONINFO resource */
+
+#define  AFS_VERINFO_FILE_DESCRIPTION "RX Performance Test (pthread)"
+#define AFS_VERINFO_NAME "rxperf"
+#define AFS_VERINFO_FILENAME "rxperf.exe"
+
+#include "AFS_component_version_number.h"
+#include "..\..\config\NTVersioninfo.rc"