*** empty log message ***
[arla.git] / rx / rxperf.c
blob83706bb70fb4e4acabb2fb54d5692c05c76f7de5
1 /*
2 * Copyright (c) 2000 - 2002 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the Institute nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
34 #ifdef HAVE_CONFIG_H
35 #include <config.h>
36 #endif
38 /*
39 * We are using getopt since we want it to be possible to link to
40 * transarc libs.
43 #define HAVE_GETRUSAGE 1
45 #ifdef RCSID
46 RCSID("$Id$");
47 #endif
49 #include <stdarg.h>
50 #include <sys/types.h>
51 #include <sys/time.h>
52 #include <sys/socket.h>
53 #include <sys/file.h>
54 #include <sys/stat.h>
55 #if HAVE_GETRUSAGE
56 #include <sys/resource.h>
57 #endif
58 #include <netinet/in.h>
59 #include <arpa/inet.h>
60 #include <netdb.h>
61 #include <stdio.h>
62 #include <stdlib.h>
63 #include <errno.h>
64 #include <string.h>
65 #include <assert.h>
66 #include <unistd.h>
67 #include <signal.h>
68 #ifdef HAVE_ERRX
69 #include <err.h> /* not stricly right, but if we have a errx() there
70 * is hopefully a err.h */
71 #endif
73 #include <roken.h> /* sometimes needed for getprogname/setprogname */
75 #include "rx.h"
76 #include "rx_globs.h"
77 #include "rx_null.h"
79 #if defined(u_int32)
80 #define uint32_t u_int32
81 #elif defined(hget32)
82 #define uint32_t afs_uint32
83 #endif
85 #ifndef HAVE_WARNX
86 static void
87 warnx(const char *fmt, ...)
89 va_list args;
91 va_start(args, fmt);
92 fprintf(stderr, "%s: ", "rxperf");
93 vfprintf (stderr, fmt, args);
94 fprintf(stderr, "\n");
95 va_end(args);
97 #endif /* !HAVE_WARNX */
99 #ifndef HAVE_ERRX
100 static void
101 errx(int eval, const char *fmt, ...)
103 va_list args;
105 va_start(args, fmt);
106 fprintf(stderr, "%s: ", "rxperf");
107 vfprintf (stderr, fmt, args);
108 fprintf(stderr, "\n");
109 va_end(args);
111 exit(eval);
113 #endif /* !HAVE_ERRX */
115 #ifndef HAVE_WARN
116 static void
117 warn(const char *fmt, ...)
119 va_list args;
120 char *errstr;
122 va_start(args, fmt);
123 fprintf(stderr, "%s: ", "rxperf");
124 vfprintf (stderr, fmt, args);
126 errstr = strerror(errno);
128 fprintf(stderr, ": %s\n", errstr ? errstr : "unknown error");
129 va_end(args);
131 #endif /* !HAVE_WARN */
133 #ifndef HAVE_ERR
134 static void
135 err(int eval, const char *fmt, ...)
137 va_list args;
138 char *errstr;
140 va_start(args, fmt);
141 fprintf(stderr, "%s: ", "rxperf");
142 vfprintf (stderr, fmt, args);
144 errstr = strerror(errno);
146 fprintf(stderr, ": %s\n", errstr ? errstr : "unknown error");
147 va_end(args);
149 exit(eval);
151 #endif /* !HAVE_ERR */
153 #define DEFAULT_PORT 7009 /* To match tcpdump */
154 #define DEFAULT_HOST "127.0.0.1"
155 #define DEFAULT_BYTES 1000000
156 #define RXPERF_BUFSIZE 10000
158 enum { RX_PERF_VERSION = 3 };
159 enum { RX_SERVER_ID = 147 };
160 enum { RX_PERF_UNKNOWN = -1, RX_PERF_SEND = 0, RX_PERF_RECV = 1,
161 RX_PERF_RPC=3, RX_PERF_FILE=4 };
163 enum { RXPERF_MAGIC_COOKIE = 0x4711 };
169 #if DEBUG
170 #define DBFPRINT(x) do { printf x ; } while(0)
171 #else
172 #define DBFPRINT(x)
173 #endif
175 static void
176 sigusr1 (int foo)
178 exit (2); /* XXX profiler */
181 static void
182 sigint (int foo)
184 rx_Finalize();
185 exit (2); /* XXX profiler */
192 static struct timeval timer_start;
193 static struct timeval timer_stop;
194 static int timer_check = 0;
196 static void
197 start_timer (void)
199 timer_check++;
200 gettimeofday (&timer_start, NULL);
207 static void
208 end_and_print_timer (char *str)
210 long long start_l, stop_l;
212 timer_check--;
213 assert (timer_check == 0);
214 gettimeofday(&timer_stop, NULL);
215 start_l = timer_start.tv_sec * 1000000 + timer_start.tv_usec;
216 stop_l = timer_stop.tv_sec * 1000000 + timer_stop.tv_usec;
217 printf("%s:\t%8llu msec\n", str, (stop_l-start_l)/1000);
224 static u_long
225 str2addr (const char *s)
227 struct in_addr server;
228 struct hostent *h;
230 #ifndef INADDR_NONE
231 #define INADDR_NONE 0xffffffff
232 #endif
233 if (inet_addr(s) != INADDR_NONE)
234 return inet_addr(s);
235 h = gethostbyname (s);
236 if (h != NULL) {
237 memcpy (&server, h->h_addr_list[0], sizeof(server));
238 return server.s_addr;
240 return 0;
248 static void
249 get_sec(int serverp, struct rx_securityClass** sec, int *secureindex)
251 if (serverp) {
252 *sec = rxnull_NewServerSecurityObject();
253 *secureindex = 1;
254 } else {
255 *sec = rxnull_NewClientSecurityObject();
256 *secureindex = 0;
261 * process the "RPC" and return the results
264 char somebuf[RXPERF_BUFSIZE];
266 int32_t rxwrite_size = sizeof(somebuf);
267 int32_t rxread_size = sizeof(somebuf);
269 static int
270 readbytes(struct rx_call *call, int32_t bytes)
272 int32_t size;
274 while (bytes > 0) {
275 size = rxread_size;
276 if (size > bytes)
277 size = bytes;
278 if (rx_Read (call, somebuf, size) != size)
279 return 1;
280 bytes -= size;
282 return 0;
285 static int
286 sendbytes(struct rx_call *call, int32_t bytes)
288 int32_t size;
290 while (bytes > 0) {
291 size = rxwrite_size;
292 if (size > bytes)
293 size = bytes;
294 if (rx_Write (call, somebuf, size) != size)
295 return 1;
296 bytes -= size;
298 return 0;
302 static int32_t
303 rxperf_ExecuteRequest(struct rx_call *call)
305 int32_t version;
306 int32_t command;
307 uint32_t bytes;
308 uint32_t recvb;
309 uint32_t sendb;
310 uint32_t data;
311 uint32_t num;
312 uint32_t *readwrite;
313 int i;
314 int readp=TRUE;
316 DBFPRINT(("got a request\n"));
318 if (rx_Read (call, &version, 4) != 4) {
319 warn ("rx_Read failed to read version");
320 return -1;
323 if (htonl(RX_PERF_VERSION) != version) {
324 warnx ("client has wrong version");
325 return -1;
328 if (rx_Read (call, &command, 4) != 4) {
329 warnx ("rx_Read failed to read command");
330 return -1;
332 command = ntohl(command);
334 if (rx_Read (call, &data, 4) != 4) {
335 warnx ("rx_Read failed to read size");
336 return -1;
338 rxread_size = ntohl(data);
339 if (rxread_size > sizeof(somebuf)) {
340 warnx("rxread_size too large %d", rxread_size);
341 return -1;
344 if (rx_Read (call, &data, 4) != 4) {
345 warnx ("rx_Read failed to write size");
346 return -1;
348 rxwrite_size = ntohl(data);
349 if (rxwrite_size > sizeof(somebuf)) {
350 warnx("rxwrite_size too large %d", rxwrite_size);
351 return -1;
354 switch (command) {
355 case RX_PERF_SEND:
356 DBFPRINT(("got a send request\n"));
358 if (rx_Read (call, &bytes, 4) != 4) {
359 warnx ("rx_Read failed to read bytes");
360 return -1;
362 bytes = ntohl(bytes);
364 DBFPRINT(("reading(%d) ", bytes));
365 readbytes(call, bytes);
367 data = htonl(RXPERF_MAGIC_COOKIE);
368 if (rx_Write (call, &data, 4) != 4) {
369 warnx ("rx_Write failed when sending back result");
370 return -1;
372 DBFPRINT(("done\n"));
374 break;
375 case RX_PERF_RPC:
376 DBFPRINT(("got a rpc request, reading commands\n"));
378 if (rx_Read (call, &recvb, 4) != 4) {
379 warnx ("rx_Read failed to read recvbytes");
380 return -1;
382 recvb = ntohl(recvb);
383 if (rx_Read (call, &sendb, 4) != 4) {
384 warnx ("rx_Read failed to read recvbytes");
385 return -1;
387 sendb = ntohl(sendb);
389 DBFPRINT(("read(%d) ", recvb));
390 if (readbytes(call, recvb)) {
391 warnx("readbytes failed");
392 return -1;
394 DBFPRINT(("send(%d) ", sendb));
395 if (sendbytes(call, sendb)) {
396 warnx("sendbytes failed");
397 return -1;
400 DBFPRINT(("done\n"));
402 data = htonl(RXPERF_MAGIC_COOKIE);
403 if (rx_Write (call, &data, 4) != 4) {
404 warnx ( "rx_Write failed when sending back magic cookie");
405 return -1;
408 break;
409 case RX_PERF_FILE:
410 if (rx_Read (call, &data, 4) != 4)
411 errx (1, "failed to read num from client");
412 num = ntohl(data);
414 readwrite = malloc(num*sizeof(uint32_t));
415 if(readwrite == NULL)
416 err(1, "malloc");
418 if (rx_Read (call, readwrite, num*sizeof(uint32_t)) !=
419 num*sizeof(uint32_t))
420 errx (1, "failed to read recvlist from client");
422 for(i=0; i < num; i++) {
423 if(readwrite[i] == 0) {
424 DBFPRINT(("readp %d", readwrite[i] ));
425 readp = !readp;
428 bytes = ntohl(readwrite[i])*sizeof(uint32_t);
430 if(readp) {
431 DBFPRINT(("read\n"));
432 readbytes(call, bytes);
433 } else {
434 sendbytes(call, bytes);
435 DBFPRINT(("send\n"));
439 break;
440 case RX_PERF_RECV:
441 DBFPRINT(("got a recv request\n"));
443 if (rx_Read (call, &bytes, 4) != 4) {
444 warnx ("rx_Read failed to read bytes");
445 return -1;
447 bytes = ntohl(bytes);
449 DBFPRINT(("sending(%d) ", bytes));
450 sendbytes(call, bytes);
452 data = htonl(RXPERF_MAGIC_COOKIE);
453 if (rx_Write (call, &data, 4) != 4) {
454 warnx ("rx_Write failed when sending back result");
455 return -1;
457 DBFPRINT(("done\n"));
459 break;
460 default:
461 warnx ("client sent a unsupported command");
462 return -1;
464 DBFPRINT(("done with command\n"));
466 return 0;
473 static void
474 do_server (int port)
476 struct rx_service *service;
477 struct rx_securityClass *secureobj;
478 int secureindex;
479 int ret;
481 ret = rx_Init (port);
482 if (ret)
483 errx (1, "rx_Init failed");
485 get_sec(1, &secureobj, &secureindex);
487 service = rx_NewService (0,
488 RX_SERVER_ID,
489 "rxperf",
490 &secureobj,
491 secureindex,
492 rxperf_ExecuteRequest);
493 if (service == NULL)
494 errx(1, "Cant create server");
496 rx_StartServer(1) ;
497 abort();
504 static void
505 readfile(const char *filename, uint32_t **readwrite, uint32_t *size)
507 FILE *f;
508 uint32_t len=16;
509 uint32_t num=0;
510 uint32_t data;
511 char *ptr;
512 char buf[RXPERF_BUFSIZE];
514 *readwrite = malloc(sizeof(uint32_t)*len);
516 if(*readwrite == NULL)
517 err(1, "malloc");
519 f=fopen(filename, "r");
520 if(f==NULL)
521 err(1, "fopen");
523 while(fgets(buf, sizeof(buf), f) != NULL) {
525 buf[strcspn(buf, "\n")] = '\0';
527 if(num >= len) {
528 len=len*2;
529 *readwrite = realloc(*readwrite, len*sizeof(uint32_t));
530 if(*readwrite == NULL)
531 err(1, "realloc");
534 if(*buf != '\0') {
535 data = htonl(strtol (buf, &ptr, 0));
536 if (ptr && ptr == buf)
537 errx (1, "can't resolve number of bytes to transfer");
538 } else {
539 data = 0;
542 (*readwrite)[num] =data;
543 num++;
546 *size = num;
549 if(fclose(f) == -1)
550 err(1, "fclose");
558 static void
559 do_client (const char *server, int port, char *filename,
560 int32_t command, int32_t times,
561 int32_t bytes, int32_t rpc_sendbytes, int32_t rpc_recvbytes)
563 struct rx_connection *conn;
564 struct rx_call *call;
565 uint32_t addr = str2addr(server);
566 struct rx_securityClass *secureobj;
567 int secureindex;
568 int32_t data;
569 uint32_t num;
570 int ret;
571 int i;
572 int readp = FALSE;
573 char stamp[1024];
574 uint32_t size;
576 uint32_t *readwrite;
578 ret = rx_Init (0);
579 if (ret)
580 errx (1, "rx_Init failed");
582 get_sec(0, &secureobj, &secureindex);
584 conn = rx_NewConnection(addr,
585 port,
586 RX_SERVER_ID,
587 secureobj,
588 secureindex);
589 if (conn == NULL)
590 errx (1, "failed to contact server");
592 if (command == RX_PERF_RPC)
593 snprintf (stamp, sizeof(stamp),
594 "send\t%d times\t%d writes\t%d reads",
595 times, rpc_sendbytes, rpc_recvbytes);
596 else
597 snprintf (stamp, sizeof(stamp),
598 "send\t%d times", times);
600 start_timer();
602 for(i=0; i < times ; i++) {
604 DBFPRINT(("starting command "));
606 call = rx_NewCall (conn);
607 if (call == NULL)
608 errx (1, "rx_NewCall failed");
610 data = htonl(RX_PERF_VERSION);
611 if (rx_Write (call, &data, 4) != 4)
612 errx (1, "rx_Write failed to send version");
614 data = htonl(command);
615 if (rx_Write (call, &data, 4) != 4)
616 errx (1, "rx_Write failed to send command");
618 data = htonl(rxread_size);
619 if (rx_Write (call, &data, 4) != 4)
620 errx (1, "rx_Write failed to send read size");
621 data = htonl(rxwrite_size);
622 if (rx_Write (call, &data, 4) != 4)
623 errx (1, "rx_Write failed to send write read");
626 switch (command) {
627 case RX_PERF_RECV:
628 DBFPRINT(("command "));
630 data = htonl (bytes);
631 if (rx_Write (call, &data, 4) != 4)
632 errx (1, "rx_Write failed to send size");
634 DBFPRINT(("sending(%d) ", bytes));
635 if (readbytes(call, bytes))
636 errx(1, "sendbytes");
638 if (rx_Read (call, &data, 4) != 4)
639 errx (1, "failed to read result from server");
641 if (data != htonl(RXPERF_MAGIC_COOKIE))
642 warn("server send wrong magic cookie in responce");
644 DBFPRINT(("done\n"));
646 break;
647 case RX_PERF_SEND:
648 DBFPRINT(("command "));
650 data = htonl (bytes);
651 if (rx_Write (call, &data, 4) != 4)
652 errx (1, "rx_Write failed to send size");
654 DBFPRINT(("sending(%d) ", bytes));
655 if (sendbytes(call, bytes))
656 errx(1, "sendbytes");
658 if (rx_Read (call, &data, 4) != 4)
659 errx (1, "failed to read result from server");
661 if (data != htonl(RXPERF_MAGIC_COOKIE))
662 warn("server send wrong magic cookie in responce");
664 DBFPRINT(("done\n"));
666 break;
667 case RX_PERF_RPC:
668 DBFPRINT(("commands "));
670 data = htonl(rpc_sendbytes);
671 if (rx_Write(call, &data, 4) != 4)
672 errx (1, "rx_Write failed to send command");
674 data = htonl(rpc_recvbytes);
675 if (rx_Write (call, &data, 4) != 4)
676 errx (1, "rx_Write failed to send command");
678 DBFPRINT(("send(%d) ", rpc_sendbytes));
679 sendbytes(call, rpc_sendbytes);
681 DBFPRINT(("recv(%d) ", rpc_recvbytes));
682 readbytes(call, rpc_recvbytes);
684 if (rx_Read (call, &bytes, 4) != 4)
685 errx (1, "failed to read result from server");
687 if (bytes != htonl(RXPERF_MAGIC_COOKIE))
688 warn("server send wrong magic cookie in responce");
690 DBFPRINT(("done\n"));
692 break;
693 case RX_PERF_FILE:
694 readfile(filename, &readwrite, &num);
696 data = htonl(num);
697 if (rx_Write(call, &data, sizeof(data)) != 4)
698 errx (1, "rx_Write failed to send size");
700 if (rx_Write(call, readwrite, num*sizeof(uint32_t))
701 != num*sizeof(uint32_t))
702 errx (1, "rx_Write failed to send list");
704 for(i=0; i < num; i++) {
705 if(readwrite[i] == 0)
706 readp = !readp;
708 size = ntohl(readwrite[i])*sizeof(uint32_t);
710 if(readp) {
711 readbytes(call, size);
712 DBFPRINT(("read\n"));
713 } else {
714 sendbytes(call, size);
715 DBFPRINT(("send\n"));
718 break;
719 default:
720 abort();
723 rx_EndCall (call, 0);
726 end_and_print_timer (stamp);
727 DBFPRINT(("done for good\n"));
729 rx_Finalize();
732 static void
733 usage()
735 #define COMMON ""
737 fprintf(stderr, "usage: %s client -c send -b <bytes>\n",
738 getprogname());
739 fprintf(stderr, "usage: %s client -c recv -b <bytes>\n",
740 getprogname());
741 fprintf(stderr, "usage: %s client -c rpc -S <rpc_sendbytes> -R <rpc_recvbytes>\n",
742 getprogname());
743 fprintf(stderr, "usage: %s client -c file -f filename\n",
744 getprogname());
745 fprintf (stderr, "%s: usage: common option to the client "
746 "-w <rx_write size> -r <rx_read size> -T times -p port -s server\n",
747 getprogname());
748 fprintf(stderr, "usage: %s server -p port\n", getprogname());
749 #undef COMMMON
750 exit(1);
754 * do argument processing and call networking functions
757 static int
758 rxperf_server (int argc, char **argv)
760 int port = DEFAULT_PORT;
761 char *ptr;
762 int ch;
764 while ((ch = getopt(argc, argv, "r:d:p:w:")) != -1) {
765 switch (ch) {
766 case 'd':
767 #ifdef RXDEBUG
768 rx_debugFile = fopen(optarg, "w");
769 if (rx_debugFile == NULL)
770 err(1, "fopen %s", optarg);
771 #else
772 errx(1, "compiled without RXDEBUG");
773 #endif
774 break;
775 case 'r':
776 rxread_size = strtol(optarg, &ptr, 0);
777 if (ptr != 0 && ptr[0] != '\0')
778 errx (1, "can't resolve readsize");
779 if (rxread_size > sizeof(somebuf))
780 errx(1, "%d > sizeof(somebuf) (%lu)",
781 rxread_size, (unsigned long)sizeof(somebuf));
782 break;
783 case 'p':
784 port = strtol(optarg, &ptr, 0);
785 if (ptr != 0 && ptr[0] != '\0')
786 errx (1, "can't resolve portname");
787 break;
788 case 'w':
789 rxwrite_size = strtol(optarg, &ptr, 0);
790 if (ptr != 0 && ptr[0] != '\0')
791 errx (1, "can't resolve writesize");
792 if (rxwrite_size > sizeof(somebuf))
793 errx(1, "%d > sizeof(somebuf) (%lu)",
794 rxwrite_size, (unsigned long)sizeof(somebuf));
795 break;
796 default:
797 usage();
801 if (optind != argc)
802 usage();
804 do_server (htons(port));
806 return 0;
810 * do argument processing and call networking functions
813 static int
814 rxperf_client (int argc, char **argv)
816 char *host = DEFAULT_HOST;
817 int bytes = DEFAULT_BYTES;
818 int port = DEFAULT_PORT;
819 char *filename = NULL;
820 int32_t cmd;
821 int rpc_sendbytes = 3;
822 int rpc_recvbytes = 30;
823 int print_stats = 0;
824 int times = 100;
825 char *ptr;
826 int ch;
828 cmd = RX_PERF_UNKNOWN;
830 while ((ch = getopt(argc, argv, "GT:S:R:b:c:d:p:r:s:w:f:")) != -1) {
831 switch (ch) {
832 case 'G':
833 print_stats = 1;
834 #ifndef HAVE_GETRUSAGE
835 printf("could not find getrusage, can't print stats\n");
836 #endif
837 break;
838 case 'b':
839 bytes = strtol (optarg, &ptr, 0);
840 if (ptr && *ptr != '\0')
841 errx (1, "can't resolve number of bytes to transfer");
842 break;
843 case 'c':
844 if (strcasecmp(optarg, "send") == 0)
845 cmd = RX_PERF_SEND;
846 else if (strcasecmp(optarg, "recv") == 0)
847 cmd = RX_PERF_RECV;
848 else if (strcasecmp(optarg, "rpc") == 0)
849 cmd = RX_PERF_RPC;
850 else if (strcasecmp(optarg, "file") == 0)
851 cmd = RX_PERF_FILE;
852 else
853 errx(1, "unknown command %s", optarg);
854 break;
855 case 'd':
856 #ifdef RXDEBUG
857 rx_debugFile = fopen(optarg, "w");
858 if (rx_debugFile == NULL)
859 err(1, "fopen %s", optarg);
860 #else
861 errx(1, "compiled without RXDEBUG");
862 #endif
863 break;
864 case 'p':
865 port = strtol(optarg, &ptr, 0);
866 if (ptr != 0 && ptr[0] != '\0')
867 errx (1, "can't resolve portname");
868 break;
869 case 'r':
870 rxread_size = strtol(optarg, &ptr, 0);
871 if (ptr != 0 && ptr[0] != '\0')
872 errx (1, "can't resolve readsize");
873 if (rxread_size > sizeof(somebuf))
874 errx(1, "%d > sizeof(somebuf) (%lu)",
875 rxread_size, (unsigned long)sizeof(somebuf));
876 break;
877 case 's':
878 host = strdup(optarg);
879 if (host == NULL)
880 err(1, "strdup");
881 break;
882 case 'w':
883 rxwrite_size = strtol(optarg, &ptr, 0);
884 if (ptr != 0 && ptr[0] != '\0')
885 errx (1, "can't resolve writesize");
886 if (rxwrite_size > sizeof(somebuf))
887 errx(1, "%d > sizeof(somebuf) (%lu)",
888 rxwrite_size, (unsigned long)sizeof(somebuf));
889 break;
890 case 'T':
891 times = strtol (optarg, &ptr, 0);
892 if (ptr && *ptr != '\0')
893 errx (1, "can't resolve number times to run the test");
894 break;
895 case 'S':
896 rpc_sendbytes = strtol (optarg, &ptr, 0);
897 if (ptr && *ptr != '\0')
898 errx (1, "can't resolve number of bytes to transfer");
899 break;
900 case 'R':
901 rpc_recvbytes = strtol (optarg, &ptr, 0);
902 if (ptr && *ptr != '\0')
903 errx (1, "can't resolve number of bytes to transfer");
904 break;
905 case 'f':
906 filename = optarg;
907 break;
908 default:
909 usage();
913 if (optind != argc)
914 usage();
916 if (cmd == RX_PERF_UNKNOWN)
917 errx(1, "no command given to the client");
919 do_client(host, htons(port), filename, cmd, times, bytes,
920 rpc_sendbytes, rpc_recvbytes);
922 #if HAVE_GETRUSAGE
923 if (print_stats) {
924 struct rusage rusage;
925 if(getrusage (RUSAGE_SELF, &rusage) < 0)
926 printf("no stats\n");
927 else
928 printf ("Status:\n"
929 "- utime = (%ld, %lu)\n"
930 "- stime = (%ld, %lu)\n"
931 "- maxrss = %ld\n"
932 "- ixrss = %ld\n"
933 "- idrss = %ld\n"
934 "- isrss = %ld\n"
935 "- minflt = %ld\n"
936 "- majflt = %ld\n"
937 "- nswap = %ld\n"
938 "- inblock = %ld\n"
939 "- oublock = %ld\n"
940 "- msgsnd = %ld\n"
941 "- msgrcv = %ld\n"
942 "- nsignals = %ld\n"
943 "- nvcsw = %lu\n"
944 "- nivcws = %lu\n",
945 rusage.ru_utime.tv_sec,
946 (unsigned long)rusage.ru_utime.tv_usec,
947 rusage.ru_stime.tv_sec,
948 (unsigned long)rusage.ru_stime.tv_usec,
949 rusage.ru_maxrss,
950 rusage.ru_ixrss,
951 rusage.ru_idrss,
952 rusage.ru_isrss,
953 rusage.ru_minflt,
954 rusage.ru_majflt,
955 rusage.ru_nswap,
956 rusage.ru_inblock,
957 rusage.ru_oublock,
958 rusage.ru_msgsnd,
959 rusage.ru_msgrcv,
960 rusage.ru_nsignals,
961 (unsigned long)rusage.ru_nvcsw,
962 (unsigned long)rusage.ru_nivcsw);
964 #endif /* HAVE_GETRUSAGE */
965 return 0;
969 * setup world and call cmd
973 main(int argc, char **argv)
975 PROCESS pid;
977 setprogname(argv[0]);
979 signal (SIGUSR1, sigusr1);
980 signal (SIGINT, sigint);
982 LWP_InitializeProcessSupport (LWP_NORMAL_PRIORITY, &pid);
984 memset (somebuf, 0, sizeof(somebuf));
986 if (argc >= 2 && strcmp(argv[1], "server") == 0)
987 rxperf_server(argc - 1, argv + 1);
988 else if (argc >= 2 && strcmp(argv[1], "client") == 0)
989 rxperf_client(argc - 1, argv + 1);
990 else
991 usage();
992 return 0;