diff options
Diffstat (limited to 'performance-tests/TTCP/ACE-C++/wrapper-new-ttcp.cpp')
-rw-r--r-- | performance-tests/TTCP/ACE-C++/wrapper-new-ttcp.cpp | 947 |
1 files changed, 947 insertions, 0 deletions
diff --git a/performance-tests/TTCP/ACE-C++/wrapper-new-ttcp.cpp b/performance-tests/TTCP/ACE-C++/wrapper-new-ttcp.cpp new file mode 100644 index 00000000000..55fbdf1d077 --- /dev/null +++ b/performance-tests/TTCP/ACE-C++/wrapper-new-ttcp.cpp @@ -0,0 +1,947 @@ +/* -*- C++ -*- */ +// @(#)wrapper-new-ttcp.cpp 1.1 10/18/96 + +/* + * T T C P . C + * + * Test TCP connection. Makes a connection on port 5001 + * and transfers fabricated buffers or data copied from stdin. + * + * Usable on 4.2, 4.3, and 4.1a systems by defining one of + * BSD42 BSD43 (BSD41a) + * Machines using System V with BSD sockets should define SYSV. + * + * Modified for operation under 4.2BSD, 18 Dec 84 + * T.C. Slattery, USNA + * Minor improvements, Mike Muuss and Terry Slattery, 16-Oct-85. + * Modified in 1989 at Silicon Graphics, Inc. + * catch SIGPIPE to be able to print stats when receiver has died + * for tcp, don't look for sentinel during reads to allow small transfers + * increased default buffer size to 8K, nbuf to 2K to transfer 16MB + * moved default port to 5001, beyond IPPORT_USERRESERVED + * make sinkmode default because it is more popular, + * -s now means don't sink/source + * count number of read/write system calls to see effects of + * blocking from full socket buffers + * for tcp, -D option turns off buffered writes (sets TCP_NODELAY sockopt) + * buffer alignment options, -A and -O + * print stats in a format that's a bit easier to use with grep & awk + * for SYSV, mimic BSD routines to use most of the existing timing code + * Modified by Steve Miller of the University of Maryland, College Park + * -b sets the socket buffer size (SO_SNDBUF/SO_RCVBUF) + * Modified Sept. 1989 at Silicon Graphics, Inc. + * restored -s sense at request of tcs@brl + * Modified Oct. 1991 at Silicon Graphics, Inc. + * use getopt(3) for option processing, add -f and -T options. + * SGI IRIX 3.3 and 4.0 releases don't need #define SYSV. + * Modified Aug.1993 at University Paderborn, Germany + * some SVR4 changes and time functions changed to itimer() calls + * Modified by Douglas C. Schmidt September 28, 1994 + * added support for testing UNIX domain socket performance + * Modified by Tim Harrison May, 1995 + * added support for ACE wrappers + * Distribution Status - + * Public Domain. Distribution Unlimited. + */ +#ifndef lint +static char RCSid[] = "ttcp.c $Revision$"; +#endif + +/* #define BSD43 */ +/* #define BSD42 */ +/* #define BSD41a */ +#define SYSV /* required on SGI IRIX releases before 3.3 */ + +#include <ace/SOCK_Connector.h> +ACE_SOCK_Connector connector_factory; + +#include <ace/SOCK_Acceptor.h> +ACE_SOCK_Acceptor acceptor_factory; + +#include <ace/INET_Addr.h> +ACE_INET_Addr address; + +#include <stdio.h> +#include <signal.h> +#include <ctype.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <malloc.h> +#include <string.h> +#include <stdlib.h> +#include <memory.h> +#include <netinet/tcp.h> +#include <arpa/inet.h> +#include <netdb.h> +#include <sys/time.h> /* struct itimerval */ +#include <limits.h> +#include <sys/un.h> +#include <unistd.h> + +#if defined(SYSV) +#define bcopy(b1,b2,n) memcpy(b2,b1,n) +#define bzero(b1,n) memset(b1,0,n) +#include <sys/times.h> +#include <sys/param.h> +struct rusage + { + struct timeval ru_utime, ru_stime; + }; +#define RUSAGE_SELF 0 + +#else +#include <sys/resource.h> +#endif + +struct sockaddr_in sinme; +struct sockaddr_un sunme; +struct sockaddr_in sinhim; +struct sockaddr_un sunhim; +struct sockaddr_in frominet; +struct sockaddr_un fromunix; + +struct Session_Control_Message +{ + long nbuf_; + // number of buffers that will be sent this round. + long size_; + // size of the buffers that will be sent +} session_control_buf; + +struct Data_Control_Message +{ + long size_; + char data_; +} *message_buf; + +int fromlen; +int domain = PF_INET; /* Default is to use Internet domain sockets. */ +char *domainname; /* Rendezvous address for UNIX domain sockets. */ +int fd; /* fd of network socket */ + +int data_buf_len = 1024 * 1024 * 2; // length of data portion +long total_msg_len; // length of entire message +char *data_buf; // pointer to data portion +int nbuf = 2 * 1024; /* number of buffers to send in sinkmode */ + +int bufoffset = 0; /* align buffer to this */ +int bufalign = 16 * 1024; /* modulo this */ + +int udp = 0; /* 0 = tcp, !0 = udp */ +int options = 0; /* socket options */ +int one = 1; /* for 4.3 BSD style setsockopt() */ +short port = 5001; /* TCP port number */ +char *host; /* ptr to name of host */ +int trans; /* 0=receive, !0=transmit mode */ +int sinkmode = 0; /* 0=normal I/O, !0=sink/source mode */ +int verbose = 0; /* 0=print basic info, 1=print cpu rate, proc + * resource usage. */ +int nodelay = 0; /* set TCP_NODELAY socket option */ +int b_flag = 0; /* use mread() */ +int sockbufsize = 0; /* socket buffer size to use */ +char fmt = 'K'; /* output format: k = kilobits, K = kilobytes, + * m = megabits, M = megabytes, + * g = gigabits, G = gigabytes */ +int touchdata = 0; /* access data after reading */ + +struct hostent *addr; +extern int errno; +extern int optind; +extern char *optarg; + +char Usage[] = "\ +Usage: ttcp -t [-options] host [ < in ]\n\ + ttcp -r [-options > out]\n\ +Common options:\n\ + -l ## length of bufs read from or written to network (default 8192)\n\ + -u use UDP instead of TCP\n\ + -U use UNIX domain sockets instead of Internet domain sockets\n\ + -p ## port number to send to or listen at (default 5001)\n\ + -s -t: source a pattern to network\n\ + -r: sink (discard) all data from network\n\ + -A align the start of buffers to this modulus (default 16384)\n\ + -O start buffers at this offset from the modulus (default 0)\n\ + -v verbose: print more statistics\n\ + -d set SO_DEBUG socket option\n\ + -b ## set socket buffer size (if supported)\n\ + -f X format for rate: k,K = kilo{bit,byte}; m,M = mega; g,G = giga\n\ +Options specific to -t:\n\ + -n## number of source bufs written to network (default 2048)\n\ + -D don't buffer TCP writes (sets TCP_NODELAY socket option)\n\ +Options specific to -r:\n\ + -B for -s, only output full blocks as specified by -l (for TAR)\n\ + -T \"touch\": access each byte as it's read\n\ +"; + +char stats[128]; +unsigned long nbytes; /* bytes on net */ +unsigned long numCalls = 0; /* # of I/O system calls */ +double cput, realt; /* user, real time (seconds) */ + +void err (char *s); +void mes (char *s); +void pattern (register char *cp, register int cnt); +char *outfmt (double b); +static void getrusage (int ignored, register struct rusage *ru); +static void gettimeofday (struct timeval *tp, struct timezone *zp); +void prep_timer (void); +double read_timer (char *str, int len); +static void prusage (register struct rusage *r0, struct rusage *r1, struct timeval *e, struct timeval *b, char *outp); +static void tvadd (struct timeval *tsum, struct timeval *t0, struct timeval *t1); +static void tvsub (struct timeval *tdiff, struct timeval *t1, struct timeval *t0); +static void psecs (long l, register char *cp); +void delay (int us); +int mread (int fd, register char *bufp, unsigned n); +int Nread (ACE_SOCK_Stream &s, void *buf, int count); +int Nwrite (ACE_SOCK_Stream &s, void *buf, int count); + +#if !defined (__cplusplus) +typedef void (*SIG_TYP)(); +#endif + +#ifdef SVR4 +void +sigpipe (int foo) +#else +void +sigpipe () +#endif +{ +} + +char *title = 0; +int new_line = 0; + +int +main (int argc, char *argv[]) +{ + ACE_SOCK_Stream connection_stream; + unsigned long addr_tmp; + int c; + + if (argc < 2) + goto usage; + + while ((c = getopt (argc, argv, "drstU:uvBDTb:f:l:n:p:A:O:L:xh:")) != -1) + { + switch (c) + { + + case 'h': + host = optarg; + break; + case 'x': + new_line = 1; + break; + case 'L': + title = optarg; + break; + case 'B': + b_flag = 1; + break; + case 't': + trans = 1; + break; + case 'r': + trans = 0; + break; + case 'd': + options |= SO_DEBUG; + break; + case 'D': +#ifdef TCP_NODELAY + nodelay = 1; +#else + fprintf (stderr, + "ttcp: -D option ignored: TCP_NODELAY socket option not supported\n"); +#endif + break; + case 'n': + nbuf = atoi (optarg); + break; + case 'l': + data_buf_len = atoi (optarg); + break; + case 's': + sinkmode = !sinkmode; + break; + case 'p': + port = atoi (optarg); + break; + case 'U': + domain = PF_UNIX; + domainname = optarg; + break; + case 'u': + udp = 1; + break; + case 'v': + verbose = 1; + break; + case 'A': + bufalign = atoi (optarg); + break; + case 'O': + bufoffset = atoi (optarg); + break; + case 'b': +#if defined(SO_SNDBUF) || defined(SO_RCVBUF) + sockbufsize = atoi (optarg); +#else + fprintf (stderr, "ttcp: -b option ignored: SO_SNDBUF/SO_RCVBUF socket options not supported\n"); +#endif + break; + case 'f': + fmt = *optarg; + break; + case 'T': + touchdata = 1; + break; + + default: + goto usage; + } + } + + /* if transmitter, create remote address to transmit to. */ + + if (trans) + { + if (address.set (port, host) == -1) + perror ("address.set"), exit (1); + } + + /* else, receiver create address to listen on */ + else + { + address.set (port); + } + + total_msg_len = sizeof (long) + data_buf_len; + + // allocate the buffer + message_buf = (Data_Control_Message *) malloc (total_msg_len); + if (message_buf == 0) + err ("malloc"); + +// if (bufalign != 0) +// message_buf += (bufalign - ((int) message_buf % bufalign) + bufoffset) % bufalign; + + // let's go ahead and set the control message for every send right now + message_buf->size_ = data_buf_len; + + session_control_buf.nbuf_ = nbuf; + session_control_buf.size_ = data_buf_len; + + // + // print out option values for trans and receiver + // + + if (trans) + { + fprintf (stdout, + "ttcp-t: data_buf_len=%d, nbuf=%d, align=%d/%d, port=%d", + data_buf_len, nbuf, bufalign, bufoffset, port); + if (sockbufsize) + fprintf (stdout, ", sockbufsize=%d", sockbufsize); + fprintf (stdout, " %s -> %s\n", + domain == PF_INET ? (udp ? "udp" : "tcp") : "unix", + host == 0 ? domainname : host); + } + else // receiver + { + fprintf (stdout, + "ttcp-r: data_buf_len=%d, nbuf=%d, align=%d/%d, port=%d", + data_buf_len, nbuf, bufalign, bufoffset, port); + if (sockbufsize) + fprintf (stdout, ", sockbufsize=%d", sockbufsize); + fprintf (stdout, " %s\n", domain == PF_INET ? (udp ? "udp" : "tcp") : "unix"); + } + + mes ("socket"); + + // + // connect and accept + // + + if (!udp) + { + signal (SIGPIPE, (SIG_TYP) sigpipe); + + /* the transmitter will set options and connect to receiver */ + if (trans) + { + if (connector_factory.connect (connection_stream, address) == -1) + perror ("connection failed"), exit (1); + fprintf (stdout, + "ttcp-t: data_buf_len=%d, nbuf=%d, align=%d/%d, port=%d", + data_buf_len, nbuf, bufalign, bufoffset, port); + + // turn off weird ack things + if (nodelay) + { + struct protoent *p = getprotobyname ("tcp"); + + if (p && connection_stream.set_option (p->p_proto, + TCP_NODELAY, + (char *)& one, + sizeof (one))) + err ("setsockopt: nodelay"); + mes ("nodelay"); + } + if (sockbufsize) + { + if (connection_stream.set_option (SOL_SOCKET, + SO_SNDBUF, + (char *) &sockbufsize, + sizeof sockbufsize) == -1) + err ("acceptor_factory.set_option"); + mes ("sndbuf"); + } + } + + /* receiver will listen for connections from the transmitter */ + else + { + if (acceptor_factory.open (address, 1) == -1) + perror ("acceptor open"), exit (1); + + ACE_INET_Addr remote_address; + + if (acceptor_factory.accept (connection_stream, + (ACE_Addr *) &remote_address) == -1) + perror ("acceptor accept"), exit (1); + + // set the window size + if (sockbufsize) + { + if (connection_stream.set_option (SOL_SOCKET, + SO_RCVBUF, + (char *) &sockbufsize, + sizeof sockbufsize) == -1) + err ("acceptor_factory.set_option"); + mes ("rcvbuf"); + } + + fprintf (stderr, "ttcp-r: accept from %s\n", remote_address.get_host_name()); + } + } + + // + // start timer + // + + errno = 0; + if (trans) + { + pattern (& (message_buf->data_), data_buf_len); + prep_timer (); + + ACE_DEBUG ((LM_DEBUG, "Sending session control message" + " nbuf %d, size %d\n", session_control_buf.nbuf_, + session_control_buf.size_)); + if (connection_stream.send_n ((char *) &session_control_buf, + sizeof (Session_Control_Message)) + != sizeof (Session_Control_Message)) + ACE_ERROR_RETURN ((LM_ERROR, "%p send session control failed\n", + "ttcp"), -1); + + long ack; + int send_result; + while (nbuf--) + { + send_result = connection_stream.send_n ((char *) message_buf, total_msg_len); + if (send_result != total_msg_len) + ACE_ERROR_RETURN ((LM_ERROR, "%p only sent %d of %d bytes on call %d\n", + "ttcp", send_result, total_msg_len, numCalls + 1), -1); + numCalls++; + nbytes += data_buf_len; + + if (connection_stream.recv_n ((char *) &ack, sizeof ack) + != sizeof ack) + ACE_ERROR_RETURN ((LM_ERROR, "%p recv of ack failed\n", + "ttcp"), -1); + + if (ack != data_buf_len) + ACE_DEBUG ((LM_DEBUG, "%received ack for only %d bytes\n", ack)); + } + } + else + { + prep_timer (); + + if (connection_stream.recv_n ((char *) &session_control_buf, + sizeof (Session_Control_Message)) + != sizeof (Session_Control_Message)) + ACE_ERROR_RETURN ((LM_ERROR, "%p recv session control failed\n", + "ttcp"), -1); + + ACE_DEBUG ((LM_DEBUG, "received session control message" + " nbuf %d, size %d\n", session_control_buf.nbuf_, + session_control_buf.size_)); + + nbuf = session_control_buf.nbuf_; + // ignore session_control_buf.size_ for now + + long cnt; + + while (nbuf--) + { + if (connection_stream.recv_n ((char *) message_buf, sizeof (long)) + != sizeof (long)) + ACE_ERROR_RETURN ((LM_ERROR, "%p recv data control failed\n", + "ttcp"), -1); + + cnt = connection_stream.recv_n (& (message_buf->data_), message_buf->size_); + if (cnt != message_buf->size_) + ACE_ERROR_RETURN ((LM_ERROR, "recv data failed\n"), -1); + + numCalls++; + nbytes += cnt; + + if (connection_stream.send_n ((char *) &cnt, sizeof cnt) + != sizeof cnt) + ACE_ERROR_RETURN ((LM_ERROR, "%p send ack failed\n", + "ttcp"), -1); + } + } + + if (errno) + err ("IO"); + + // + // stop the timer + // + + (void) read_timer (stats, sizeof (stats)); + if (udp && trans) + { + (void) Nwrite (connection_stream, message_buf, 4); /* rcvr end */ + (void) Nwrite (connection_stream, message_buf, 4); /* rcvr end */ + (void) Nwrite (connection_stream, message_buf, 4); /* rcvr end */ + (void) Nwrite (connection_stream, message_buf, 4); /* rcvr end */ + } + if (cput <= 0.0) + cput = 0.001; + if (realt <= 0.0) + realt = 0.001; + +#if defined (LM_RESULTS) + if (trans && (title != 0)) + { + double tmp; + FILE *fd; + char filename[BUFSIZ]; + ACE_OS::sprintf (filename, "%s.results", title); + fd = fopen(filename,"a+"); + if (new_line) + fprintf(fd,"\n -l %ldk \t", data_buf_len/1024); + tmp = ((double) nbytes) / realt; + fprintf(fd,"%.2f ", tmp * 8.0 / 1024.0 / 1024.0); + fclose(fd); + } +#endif + + fprintf (stdout, + "ttcp%s: %ld bytes in %.2f real seconds = %s/sec +++\n", + trans ? "-t" : "-r", + nbytes, realt, outfmt (((double) nbytes) / realt)); + if (verbose) + { + fprintf (stdout, + "ttcp%s: %ld bytes in %.2f CPU seconds = %s/cpu sec\n", + trans ? "-t" : "-r", + nbytes, cput, outfmt (((double) nbytes) / cput)); + } + fprintf (stdout, + "ttcp%s: %d I/O calls, msec/call = %.2f, calls/sec = %.2f\n", + trans ? "-t" : "-r", + numCalls, + 1024.0 * realt / ((double) numCalls), + ((double) numCalls) / realt); + fprintf (stdout, "ttcp%s: %s\n", trans ? "-t" : "-r", stats); + if (verbose) + { + fprintf (stdout, + "ttcp%s: buffer address %#x\n", + trans ? "-t" : "-r", + message_buf); + } + exit (0); + +usage: + fprintf (stderr, Usage); + return 1; +} + +void +err (char *s) +{ + fprintf (stderr, "ttcp%s: ", trans ? "-t" : "-r"); + perror (s); + fprintf (stderr, "errno=%d\n", errno); + exit (1); +} + +void +mes (char *s) +{ + fprintf (stderr, "ttcp%s: %s\n", trans ? "-t" : "-r", s); +} + +void +pattern (register char *cp, register int cnt) +{ + register char c; + c = 0; + while (cnt-- > 0) + { + while (!isprint ((c & 0x7F))) + c++; + *cp++ = (c++ & 0x7F); + } +} + +char * +outfmt (double b) +{ + static char obuf[50]; + switch (fmt) + { + case 'G': + sprintf (obuf, "%.2f GB", b / 1024.0 / 1024.0 / 1024.0); + break; + default: + case 'K': + sprintf (obuf, "%.2f KB", b / 1024.0); + break; + case 'M': + sprintf (obuf, "%.2f MB", b / 1024.0 / 1024.0); + break; + case 'g': + sprintf (obuf, "%.2f Gbit", b * 8.0 / 1024.0 / 1024.0 / 1024.0); + break; + case 'k': + sprintf (obuf, "%.2f Kbit", b * 8.0 / 1024.0); + break; + case 'm': + sprintf (obuf, "%.2f Mbit", b * 8.0 / 1024.0 / 1024.0); + break; + } + return obuf; +} + +static struct itimerval itime0; /* Time at which timing started */ +static struct rusage ru0; /* Resource utilization at the start */ + +#if defined(SYSV) +/*ARGSUSED */ +static void +getrusage (int ignored, register struct rusage *ru) +{ + struct tms buf; + + times (&buf); + + /* Assumption: HZ <= 2147 (LONG_MAX/1000000) */ + ru->ru_stime.tv_sec = buf.tms_stime / HZ; + ru->ru_stime.tv_usec = ((buf.tms_stime % HZ) * 1000000) / HZ; + ru->ru_utime.tv_sec = buf.tms_utime / HZ; + ru->ru_utime.tv_usec = ((buf.tms_utime % HZ) * 1000000) / HZ; +} + +/*ARGSUSED */ +static void +gettimeofday (struct timeval *tp, struct timezone *zp) +{ + tp->tv_sec = time (0); + tp->tv_usec = 0; +} +#endif /* SYSV */ +/* + * P R E P _ T I M E R + */ +void +prep_timer () +{ + itime0.it_interval.tv_sec = 0; + itime0.it_interval.tv_usec = 0; + itime0.it_value.tv_sec = LONG_MAX / 22; /* greatest possible value , itimer() count backwards */ + itime0.it_value.tv_usec = 0; + + + getrusage (RUSAGE_SELF, &ru0); + + /* Init REAL Timer */ + if (setitimer (ITIMER_REAL, &itime0, NULL)) + { + perror ("Setting 'itimer' REAL failed"); + return; + } + +} + +/* + * R E A D _ T I M E R + * + */ +double +read_timer (char *str, int len) +{ + struct itimerval itimedol; + struct rusage ru1; + struct timeval td; + struct timeval tend, tstart; + char line[132]; + + getrusage (RUSAGE_SELF, &ru1); + + if (getitimer (ITIMER_REAL, &itimedol)) + { + perror ("Getting 'itimer' REAL failed"); + return (0.0); + } + + prusage (&ru0, &ru1, &itime0.it_value, &itimedol.it_value, line); + (void) strncpy (str, line, len); + + /* Get real time */ + tvsub (&td, &itime0.it_value, &itimedol.it_value); + realt = td.tv_sec + ((double) td.tv_usec) / 1000000; + + /* Get CPU time (user+sys) */ + tvadd (&tend, &ru1.ru_utime, &ru1.ru_stime); + tvadd (&tstart, &ru0.ru_utime, &ru0.ru_stime); + tvsub (&td, &tend, &tstart); + cput = td.tv_sec + ((double) td.tv_usec) / 1000000; + if (cput < 0.00001) + cput = 0.00001; + return (cput); +} + +static void +prusage (register struct rusage *r0, struct rusage *r1, + struct timeval *e, struct timeval *b, char *outp) +{ + struct timeval tdiff; + register time_t t; + register char *cp; + register int i; + int ms; + + t = (r1->ru_utime.tv_sec - r0->ru_utime.tv_sec) * 100 + + (r1->ru_utime.tv_usec - r0->ru_utime.tv_usec) / 10000 + + (r1->ru_stime.tv_sec - r0->ru_stime.tv_sec) * 100 + + (r1->ru_stime.tv_usec - r0->ru_stime.tv_usec) / 10000; + ms = (e->tv_sec - b->tv_sec) * 100 + (e->tv_usec - b->tv_usec) / 10000; + +#define END(x) {while(*x) x++;} +#if defined(SYSV) + cp = "%Uuser %Ssys %Ereal %P"; +#else +#if defined(sgi) /* IRIX 3.3 will show 0 for %M,%F,%R,%C */ + cp = "%Uuser %Ssys %Ereal %P %Mmaxrss %F+%Rpf %Ccsw"; +#else + cp = "%Uuser %Ssys %Ereal %P %Xi+%Dd %Mmaxrss %F+%Rpf %Ccsw"; +#endif +#endif + for (; *cp; cp++) + { + if (*cp != '%') + *outp++ = *cp; + else if (cp[1]) + switch (*++cp) + { + + case 'U': + tvsub (&tdiff, &r1->ru_utime, &r0->ru_utime); + sprintf (outp, "%d.%01d", tdiff.tv_sec, tdiff.tv_usec / 100000); + END (outp); + break; + + case 'S': + tvsub (&tdiff, &r1->ru_stime, &r0->ru_stime); + sprintf (outp, "%d.%01d", tdiff.tv_sec, tdiff.tv_usec / 100000); + END (outp); + break; + + case 'E': + psecs (ms / 100, outp); + END (outp); + break; + + case 'P': + sprintf (outp, "%d%%", (int) (t * 100 / ((ms ? ms : 1)))); + END (outp); + break; + +#if !defined(SYSV) + case 'W': + i = r1->ru_nswap - r0->ru_nswap; + sprintf (outp, "%d", i); + END (outp); + break; + + case 'X': + sprintf (outp, "%d", t == 0 ? 0 : (r1->ru_ixrss - r0->ru_ixrss) / t); + END (outp); + break; + + case 'D': + sprintf (outp, "%d", t == 0 ? 0 : + (r1->ru_idrss + r1->ru_isrss - (r0->ru_idrss + r0->ru_isrss)) / t); + END (outp); + break; + + case 'K': + sprintf (outp, "%d", t == 0 ? 0 : + ((r1->ru_ixrss + r1->ru_isrss + r1->ru_idrss) - + (r0->ru_ixrss + r0->ru_idrss + r0->ru_isrss)) / t); + END (outp); + break; + + case 'M': + sprintf (outp, "%d", r1->ru_maxrss / 2); + END (outp); + break; + + case 'F': + sprintf (outp, "%d", r1->ru_majflt - r0->ru_majflt); + END (outp); + break; + + case 'R': + sprintf (outp, "%d", r1->ru_minflt - r0->ru_minflt); + END (outp); + break; + + case 'I': + sprintf (outp, "%d", r1->ru_inblock - r0->ru_inblock); + END (outp); + break; + + case 'O': + sprintf (outp, "%d", r1->ru_oublock - r0->ru_oublock); + END (outp); + break; + case 'C': + sprintf (outp, "%d+%d", r1->ru_nvcsw - r0->ru_nvcsw, + r1->ru_nivcsw - r0->ru_nivcsw); + END (outp); + break; +#endif /* !SYSV */ + } + } + *outp = '\0'; +} + +static void +tvadd (struct timeval *tsum, struct timeval *t0, struct timeval *t1) +{ + + tsum->tv_sec = t0->tv_sec + t1->tv_sec; + tsum->tv_usec = t0->tv_usec + t1->tv_usec; + if (tsum->tv_usec > 1000000) + tsum->tv_sec++, tsum->tv_usec -= 1000000; +} + +static void +tvsub (struct timeval *tdiff, struct timeval *t1, struct timeval *t0) +{ + + tdiff->tv_sec = t1->tv_sec - t0->tv_sec; + tdiff->tv_usec = t1->tv_usec - t0->tv_usec; + if (tdiff->tv_usec < 0) + tdiff->tv_sec--, tdiff->tv_usec += 1000000; +} + +static void +psecs (long l, register char *cp) +{ + register int i; + + i = l / 3600; + if (i) + { + sprintf (cp, "%d:", i); + END (cp); + i = l % 3600; + sprintf (cp, "%d%d", (i / 60) / 10, (i / 60) % 10); + END (cp); + } + else + { + i = l; + sprintf (cp, "%d", i / 60); + END (cp); + } + i %= 60; + *cp++ = ':'; + sprintf (cp, "%d%d", i / 10, i % 10); +} + +/* + * N R E A D + */ +int +Nread (ACE_SOCK_Stream &s, void *buf, int count) +{ + numCalls++; + return (s.recv (buf, count)); +} + +/* + * N W R I T E + */ +int +Nwrite (ACE_SOCK_Stream &s, void *buf, int count) +{ + numCalls++; + return s.send (buf, count); +} + +void +delay (int us) +{ + struct timeval tv; + + tv.tv_sec = 0; + tv.tv_usec = us; + (void) select (1, (fd_set *) 0, (fd_set *) 0, (fd_set *) 0, &tv); +} + +/* + * M R E A D + * + * This function performs the function of a read(II) but will + * call read(II) multiple times in order to get the requested + * number of characters. This can be necessary because + * network connections don't deliver data with the same + * grouping as it is written with. Written by Robert S. Miles, BRL. + */ +int +mread (int fd, register char *bufp, unsigned n) +{ + register unsigned count = 0; + register int nread; + + do + { + nread = read (fd, bufp, n - count); + numCalls++; + if (nread < 0) + { + perror ("ttcp_mread"); + return (-1); + } + if (nread == 0) + return ((int) count); + count += (unsigned) nread; + bufp += nread; + } + while (count < n); + + return ((int) count); +} |