summaryrefslogtreecommitdiff
path: root/performance-tests/UDP
diff options
context:
space:
mode:
authorlevine <levine@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1998-03-20 18:13:27 +0000
committerlevine <levine@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1998-03-20 18:13:27 +0000
commitdf83707fad7a253bbfada587adb67543083d3df6 (patch)
tree8d994e260a3169b3091284c0b3b31126ceda0a48 /performance-tests/UDP
parent24b3e3d3cbcf56a6deb2ed9f2b9654916660c318 (diff)
downloadATCD-df83707fad7a253bbfada587adb67543083d3df6.tar.gz
added udp_test.cpp
Diffstat (limited to 'performance-tests/UDP')
-rw-r--r--performance-tests/UDP/Makefile78
-rw-r--r--performance-tests/UDP/udp_test.cpp615
2 files changed, 693 insertions, 0 deletions
diff --git a/performance-tests/UDP/Makefile b/performance-tests/UDP/Makefile
new file mode 100644
index 00000000000..5e561fb2edc
--- /dev/null
+++ b/performance-tests/UDP/Makefile
@@ -0,0 +1,78 @@
+#----------------------------------------------------------------------------
+# @(#)Makefile 1.1 10/18/96
+#
+# Makefile for tests of the miscellaneous ACE performance tests
+#----------------------------------------------------------------------------
+
+#----------------------------------------------------------------------------
+# Local macros
+#----------------------------------------------------------------------------
+
+BIN = udp_test
+
+BUILD = $(VBIN)
+
+# For make depend.
+SRC = $(addsuffix .cpp, $(BIN))
+
+#----------------------------------------------------------------------------
+# Include macros and targets
+#----------------------------------------------------------------------------
+
+include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU
+include $(ACE_ROOT)/include/makeinclude/macros.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.common.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.lib.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.local.GNU
+
+#----------------------------------------------------------------------------
+# Local targets
+#----------------------------------------------------------------------------
+
+#----------------------------------------------------------------------------
+# Dependencies
+#----------------------------------------------------------------------------
+
+# DO NOT DELETE THIS LINE -- g++dep uses it.
+# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
+
+.obj/udp_test.o .obj/udp_test.so .shobj/udp_test.o .shobj/udp_test.so: udp_test.cpp \
+ $(ACE_ROOT)/ace/Reactor.h \
+ $(ACE_ROOT)/ace/Handle_Set.h \
+ $(ACE_ROOT)/ace/ACE.h \
+ $(ACE_ROOT)/ace/OS.h \
+ $(ACE_ROOT)/ace/inc_user_config.h \
+ $(ACE_ROOT)/ace/config.h \
+ $(ACE_ROOT)/ace/streams.h \
+ $(ACE_ROOT)/ace/Basic_Types.h \
+ $(ACE_ROOT)/ace/Trace.h \
+ $(ACE_ROOT)/ace/Log_Msg.h \
+ $(ACE_ROOT)/ace/Log_Record.h \
+ $(ACE_ROOT)/ace/Log_Priority.h \
+ $(ACE_ROOT)/ace/Log_Record.i \
+ $(ACE_ROOT)/ace/Version.h \
+ $(ACE_ROOT)/ace/ACE.i \
+ $(ACE_ROOT)/ace/Timer_Queue.h \
+ $(ACE_ROOT)/ace/Synch.h \
+ $(ACE_ROOT)/ace/SV_Semaphore_Complex.h \
+ $(ACE_ROOT)/ace/SV_Semaphore_Simple.h \
+ $(ACE_ROOT)/ace/SV_Semaphore_Simple.i \
+ $(ACE_ROOT)/ace/SV_Semaphore_Complex.i \
+ $(ACE_ROOT)/ace/Synch_T.h \
+ $(ACE_ROOT)/ace/Event_Handler.h \
+ $(ACE_ROOT)/ace/Timer_Queue_T.h \
+ $(ACE_ROOT)/ace/Free_List.h \
+ $(ACE_ROOT)/ace/Signal.h \
+ $(ACE_ROOT)/ace/Containers.h \
+ $(ACE_ROOT)/ace/SOCK_Dgram.h \
+ $(ACE_ROOT)/ace/SOCK.h \
+ $(ACE_ROOT)/ace/Addr.h \
+ $(ACE_ROOT)/ace/IPC_SAP.h \
+ $(ACE_ROOT)/ace/IPC_SAP.i \
+ $(ACE_ROOT)/ace/SOCK.i \
+ $(ACE_ROOT)/ace/SOCK_Dgram.i \
+ $(ACE_ROOT)/ace/INET_Addr.h
+
+# IF YOU PUT ANYTHING HERE IT WILL GO AWAY
diff --git a/performance-tests/UDP/udp_test.cpp b/performance-tests/UDP/udp_test.cpp
new file mode 100644
index 00000000000..0458e8dfca0
--- /dev/null
+++ b/performance-tests/UDP/udp_test.cpp
@@ -0,0 +1,615 @@
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// performance-tests/UDP
+//
+// = FILENAME
+// udp_test.cpp
+//
+// = DESCRIPTION
+// Measures UDP round-trip performance.
+//
+// = AUTHORS
+// Fred Kuhns and David L. Levine
+//
+// ============================================================================
+
+#include "ace/Reactor.h"
+#include "ace/SOCK_Dgram.h"
+#include "ace/INET_Addr.h"
+#include "ace/ACE.h"
+#include <math.h>
+
+extern char *optarg;
+extern int optind;
+
+#define DEFPORT 5050
+#define MAXPKTSZ 65536
+#define DEFPKTSZ 64
+#define DEFITERATIONS 1000
+#define DEFINTERVAL 1000 /* 1000 usecs */
+#define DEFWINDOWSZ 10 /* 10 microsecond */
+char SendBuf[MAXPKTSZ];
+char RxBuf[MAXPKTSZ];
+char **cmd, *target, targethost[MAXHOSTNAMELEN], targetip[MAXHOSTNAMELEN];
+char datafile[MAXHOSTNAMELEN];
+
+ACE_UINT32 nsamples=DEFITERATIONS;
+int usdelay=DEFINTERVAL;
+int bufsz=DEFPKTSZ;
+int window=DEFWINDOWSZ, VERBOSE=0, logfile=0, server=0, client=0;
+ACE_hrtime_t max_allow=0, total_ltime, ltime;
+
+void
+usage ()
+{
+ ACE_OS::printf("%s\n"
+ "[-w window_size]\n"
+ " [-f datafile] (creates datafile.samp and datafile.dist)\n"
+ " [-v] (Verbose)\n"
+ " [-b send_bufsz]\n"
+ " [-n nsamples]\n"
+ " [-I usdelay]\n"
+ " [-s so_bufsz] \n"
+ " [-p port]\n"
+ " [-t]\n"
+ " [-r]\n"
+ " [-x max_sample_allowed]\n"
+ " targethost \n", *cmd);
+}
+
+ACE_hrtime_t *Samples;
+u_int *Dist;
+char sumfile[30], distfile[30], sampfile[30];
+
+class Client : public ACE_Event_Handler
+{
+public:
+ Client (const ACE_INET_Addr &addr, const ACE_INET_Addr &remote_addr);
+
+ virtual ~Client (void);
+
+ // Override <ACE_Event_Handler> methods.
+ virtual ACE_HANDLE get_handle (void) const;
+ virtual int handle_input (ACE_HANDLE);
+ virtual int handle_close (ACE_HANDLE handle, ACE_Reactor_Mask close_mask);
+
+ int send (const char *buf, size_t len);
+ // Send the <buf> to the server.
+
+ int get_response (char *buf, size_t len);
+ // Wait for the response.
+
+ int run (void);
+ // Send messages to server and record statistics.
+
+ int shutdown (void);
+ // Send shutdown message to server.
+
+private:
+ ACE_SOCK_Dgram endpoint_;
+ // To send messages and receive responses.
+
+ ACE_INET_Addr remote_addr_;
+ // The address to send messages to.
+
+ ACE_UNIMPLEMENTED_FUNC (Client (void))
+ ACE_UNIMPLEMENTED_FUNC (Client (const Client &))
+ ACE_UNIMPLEMENTED_FUNC (Client &operator= (const Client &))
+};
+
+Client::Client (const ACE_INET_Addr &addr, const ACE_INET_Addr &remote_addr)
+ : endpoint_ (addr),
+ remote_addr_ (remote_addr)
+{
+ if (ACE_Reactor::instance ()->register_handler
+ (this, ACE_Event_Handler::READ_MASK) == -1)
+ ACE_ERROR ((LM_ERROR,
+ "ACE_Reactor::register_handler: Client\n"));
+}
+
+Client::~Client ()
+{
+}
+
+ACE_INLINE
+ACE_HANDLE
+Client::get_handle (void) const
+{
+ return endpoint_.get_handle ();
+}
+
+int
+Client::handle_input (ACE_HANDLE)
+{
+ char buf[BUFSIZ];
+ ACE_INET_Addr from_addr;
+
+ ssize_t n = endpoint_.recv (buf, sizeof buf, from_addr);
+
+ if (n == -1)
+ ACE_ERROR ((LM_ERROR, "%p\n", "handle_input"));
+ else
+ ACE_DEBUG ((LM_DEBUG, "(%P|%t) buf of size %d = %*s\n", n, n, buf));
+
+ return 0;
+}
+
+int
+Client::handle_close (ACE_HANDLE, ACE_Reactor_Mask)
+{
+ endpoint_.close ();
+
+ return 0;
+}
+
+int
+Client::send (const char *buf, size_t len)
+{
+ return endpoint_.send (buf, len, remote_addr_);
+}
+
+
+int
+Client::get_response (char *buf, size_t len)
+{
+ ACE_INET_Addr addr;
+ return endpoint_.recv (buf, len, addr);
+}
+
+int
+Client::run (void)
+{
+ int ndist = 0, i, j, n;
+ int maxindx = 0, minindx = 0;
+ char *sbuf = SendBuf;
+ char *rbuf = RxBuf;
+ ACE_hrtime_t start, end, sample;
+#if defined (ACE_LACKS_FLOATING_POINT)
+ ACE_hrtime_t sample_mean;
+#else /* ! ACE_LACKS_FLOATING_POINT */
+ int d;
+ double std_dev, std_err, sample_mean;
+#endif /* ! ACE_LACKS_FLOATING_POINT */
+ ACE_hrtime_t last_over=0, psum=0, sum=0, max=0,
+ min = (ACE_hrtime_t) (u_int) -1;
+ FILE *sumfp = 0, *distfp = 0, *sampfp = 0;
+ pid_t *pid = (pid_t *) sbuf;
+ int *seq = (int *) (sbuf + sizeof(int));
+
+ ACE_OS::memset (sbuf, 0, bufsz);
+ ACE_OS::memset (rbuf, 0, bufsz);
+
+ *pid = ACE_OS::getpid ();
+ *seq = 0;
+
+ ACE_DEBUG ((LM_INFO, "PID = %d, Starting SEQ = %d\n", *pid, *seq));
+
+ /* Allocate memory to hold samples */
+ Samples = (ACE_hrtime_t *) ACE_OS::calloc (nsamples, sizeof (ACE_hrtime_t));
+ for (i=-1, *seq=0, j=0; i < (ACE_INT32) nsamples; (*seq)++, i++, j++)
+ {
+ start = ACE_OS::gethrtime ();
+ if (send (sbuf, bufsz) <= 0)
+ {
+ ACE_DEBUG ((LM_ERROR, "(%P) %p\n", "send"));
+ return -1;
+ }
+ if ((n = get_response (rbuf, bufsz)) <= 0)
+ {
+ ACE_DEBUG ((LM_ERROR, "(%P) %p\n", "get_response"));
+ return -1;
+ }
+
+ end = ACE_OS::gethrtime ();
+
+ if (n <= 0)
+ {
+ ACE_OS::printf("\nTrouble receiving from socket!\n\n");
+ return -1;
+ }
+
+ sample = end - start; /* in nanoseconds */
+
+ if (i < 0 )
+ {
+ ACE_OS::printf("Ignoring first sample of %lld usecs\n", sample/1000);
+ continue;
+ }
+ else if (max_allow > 0 && sample > max_allow)
+ {
+ ACE_OS::printf ("Sample # %i = "
+ "%lld msec is over the limit (%lld)!\n",
+ i, sample/1000000, max_allow/1000000);
+ if (last_over > 0)
+ ACE_OS::printf("\tTime since last over = %lld msec!\n",
+ (end - last_over)/1000000);
+ last_over = end;
+ i--;
+ continue;
+ }
+
+ Samples[i] = sample;
+ sum += sample;
+
+ if (min == (ACE_hrtime_t) (u_int) -1)
+ {
+ min = sample;
+ minindx = i;
+ }
+ if (sample > max)
+ {
+ max = sample;
+ maxindx = i;
+ }
+ if (sample < min)
+ {
+ min = sample;
+ minindx = i;
+ }
+
+ if (VERBOSE)
+ {
+ psum += sample;
+ if (j == 500)
+ {
+ /* ACE_OS::printf ("%i) Elapsed time = %lld usecs\n",
+ i-1, sample/1000); */
+ ACE_OS::printf ("%i) Partial (running) mean %lld usecs\n",
+ i+1, psum/(1000*500));
+ j = 0;
+ psum = 0;
+ }
+ }
+ }
+
+#if defined (ACE_LACKS_FLOATING_POINT)
+ sample_mean = sum / nsamples;
+#else /* ! ACE_LACKS_FLOATING_POINT */
+ sample_mean = ((double)sum)/((double)nsamples);
+#endif /* ! ACE_LACKS_FLOATING_POINT */
+
+ if (logfile)
+ {
+ ACE_OS::sprintf(sumfile, "%s.sum", datafile);
+ ACE_OS::sprintf(distfile, "%s.dist", datafile);
+ ACE_OS::sprintf(sampfile, "%s.samp", datafile);
+ if ((distfp = fopen(distfile, "w")) == NULL)
+ {
+ ACE_OS::printf("Unable to open dist file!\n\n");
+ logfile = 0;
+ }
+ if (logfile && (sampfp = fopen(sampfile, "w")) == NULL)
+ {
+ fclose(distfp);
+ ACE_OS::printf("Unable to open sample file!\n\n");
+ logfile = 0;
+ }
+ if (logfile && (sumfp = fopen(sumfile, "w")) == NULL)
+ {
+ fclose(distfp);
+ fclose(sampfp);
+ ACE_OS::printf("Unable to open sample file!\n\n");
+ logfile = 0;
+ }
+ }
+
+ if (window)
+ {
+ window = window * 1000; /* convert to nsec */
+ ndist = (int)((max-min)/window) +1;
+ Dist = (u_int *)calloc(ndist, sizeof(u_int));
+ }
+
+#if ! defined (ACE_LACKS_FLOATING_POINT)
+ std_dev = std_err = 0;
+ for (i=0; i<nsamples; i++)
+ {
+ std_dev += ((double)Samples[i] - sample_mean) *
+ ((double)Samples[i] - sample_mean);
+ d = (int)((Samples[i] - min)/window);
+ if (d < 0 || d > ndist)
+ {
+ ACE_OS::printf("\nError indexing into dist array %d (%d)\n\n",
+ d, ndist);
+ ACE_OS::exit (1);
+ }
+ Dist[d] += 1;
+ if (logfile)
+ ACE_OS::fprintf(sampfp, "%lld\n", Samples[i]);
+ }
+#endif /* ACE_LACKS_FLOATING_POINT */
+
+ if (logfile)
+ {
+ ACE_hrtime_t tmp;
+ tmp = min + (window / 2);
+ for (i=0;i<ndist;i++)
+ {
+ ACE_OS::fprintf(distfp, "%lld %d\n", tmp/1000, Dist[i]);
+ tmp += window;
+ }
+ }
+
+#if defined (ACE_LACKS_FLOATING_POINT)
+ ACE_OS::printf("\nResults for %i samples (usec):\n"
+ "\tSample Mean = %u,\n"
+ "\tSample Max = %u, Max index = %u,\n"
+ "\tSample Min = %u, Min index = %u,\n",
+ nsamples,
+ sample_mean/(ACE_UINT32) 1000,
+ max/(ACE_UINT32)1000, maxindx, min/(ACE_UINT32)1000, minindx);
+#else /* ! ACE_LACKS_FLOATING_POINT */
+ std_dev = (double) sqrt(std_dev/(double)(nsamples - 1.0));
+ std_err = (double) std_dev/sqrt((double)nsamples);
+
+ ACE_OS::printf("\nResults for %i samples (usec):\n"
+ "\tSample Mean = %f,\n"
+ "\tSample Max = %lld, Max index = %d,\n"
+ "\tSample Min = %lld, Min index = %d,\n"
+ "\tStandard Deviation = %f,\n"
+ "\tStandard Error = %f\n",
+ nsamples,
+ sample_mean/1000,
+ max/1000, maxindx, min/1000, minindx,
+ std_dev/1000, std_err/1000);
+
+ if (logfile)
+ {
+ ACE_OS::fprintf (sumfp, "Command executed: \n");
+ for (; *cmd; cmd++)
+ ACE_OS::fprintf(sumfp, "%s ", *cmd);
+ ACE_OS::fprintf(sumfp, "\n");
+ ACE_OS::fprintf(sumfp, "\nResults for %i samples (usec):"
+ "\tSample Mean = %f,\n"
+ "\tSample Max = %lld, Max index = %d,\n"
+ "\tSample Min = %lld, Min index = %d,\n"
+ "\tStandard Deviation = %f,\n"
+ "\tStandard Error = %f\n",
+ nsamples,
+ sample_mean/1000,
+ max/1000, maxindx, min/1000, minindx,
+ std_dev/1000, std_err/1000);
+ }
+#endif /* ! ACE_LACKS_FLOATING_POINT */
+
+ return 0;
+}
+
+int
+Client::shutdown (void)
+{
+ const char buf = 'S';
+
+ const int n = endpoint_.send (&buf, 1u, remote_addr_);
+
+ if (ACE_Reactor::instance ()->remove_handler
+ (this, ACE_Event_Handler::READ_MASK) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "ACE_Reactor::remove_handler: Client\n"),
+ -1);
+
+ return n;
+}
+
+class Server : public ACE_Event_Handler
+{
+public:
+ Server (const ACE_INET_Addr &addr);
+
+ virtual ~Server (void);
+
+ // Override <ACE_Event_Handler> methods.
+ virtual ACE_HANDLE get_handle (void) const;
+ virtual int handle_input (ACE_HANDLE);
+ virtual int handle_close (ACE_HANDLE handle, ACE_Reactor_Mask close_mask);
+
+private:
+ ACE_SOCK_Dgram endpoint_;
+ // Receives datagrams.
+
+ ACE_UNIMPLEMENTED_FUNC (Server (void))
+ ACE_UNIMPLEMENTED_FUNC (Server (const Server &))
+ ACE_UNIMPLEMENTED_FUNC (Server &operator= (const Server &))
+};
+
+Server::Server (const ACE_INET_Addr &addr)
+ : endpoint_ (addr)
+{
+ if (ACE_Reactor::instance ()->register_handler
+ (this, ACE_Event_Handler::READ_MASK) == -1)
+ ACE_ERROR ((LM_ERROR,
+ "ACE_Reactor::register_handler: Server\n"));
+}
+
+Server::~Server ()
+{
+}
+
+ACE_INLINE
+ACE_HANDLE
+Server::get_handle (void) const
+{
+ return endpoint_.get_handle ();
+}
+
+int
+Server::handle_input (ACE_HANDLE)
+{
+ char buf[BUFSIZ];
+ ACE_INET_Addr from_addr;
+
+ ssize_t n = endpoint_.recv (buf, sizeof buf, from_addr);
+
+ if (n == -1)
+ ACE_DEBUG ((LM_ERROR, "%p\n", "handle_input: recv"));
+
+ // Send the message back as the response.
+ if (endpoint_.send (buf, n, from_addr) == n)
+ {
+ if (n == 1 && buf[0] == 'S')
+ {
+ if (ACE_Reactor::instance ()->remove_handler
+ (this, ACE_Event_Handler::READ_MASK) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "ACE_Reactor::remove_handler: server\n"),
+ -1);
+
+ ACE_Reactor::end_event_loop ();
+ }
+
+ return 0;
+ }
+ else
+ {
+ ACE_DEBUG ((LM_ERROR, "%p\n", "handle_input: send"));
+ return -1;
+ }
+}
+
+int
+Server::handle_close (ACE_HANDLE, ACE_Reactor_Mask)
+{
+ endpoint_.close ();
+
+ return 0;
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ int c, dstport=DEFPORT;
+ int so_bufsz=0;
+
+ cmd = argv;
+
+ while ((c = getopt(argc, argv, "x:w:f:vs:I:p:rtn:b:")) != -1)
+ {
+ switch ((char) c)
+ {
+ case 'x':
+ max_allow = atoi (optarg);
+ break;
+ case 'w':
+ if ((window = atoi(optarg)) < 0)
+ {
+ ACE_OS::printf("Invalid window!\n\n");
+ return 1;
+ }
+ break;
+ case 'f':
+ strcpy(datafile, optarg);
+ logfile = 1;
+ break;
+ case 'v':
+ VERBOSE = 1;
+ break;
+ case 'b':
+ if ((bufsz = atoi(optarg)) <= 0)
+ {
+ ACE_OS::printf("\nBuffer size must be greater than 0!\n\n");
+ return 1;
+ }
+ case 'n':
+ if ((nsamples = atoi(optarg)) <= 0)
+ {
+ ACE_OS::printf("\nIterations must be greater than 0!\n\n");
+ return 1;
+ }
+ break;
+ case 's':
+ if ((so_bufsz=atoi(optarg)) <= 0)
+ {
+ ACE_OS::printf("\nInvalid socket buffer size!\n\n");
+ return 1;
+ }
+ break;
+ case 'I':
+ if (atoi(optarg) == 0)
+ {
+ ACE_OS::fprintf(stderr, "%s: bad usdelay: %s\n", argv[0],
+ optarg);
+ return 1;
+ }
+ usdelay = atoi(optarg);
+ break;
+ case 'p':
+ if ((dstport = atoi(optarg)) <= 0)
+ {
+ ACE_OS::printf("\nInvalid port number!\n\n");
+ usage ();
+ return 1;
+ }
+ break;
+ case 't':
+ server = 0;
+ client = 1;
+ break;
+ case 'r':
+ client = 0;
+ server = 1;
+ break;
+ default:
+ usage ();
+ return 1;
+ }
+ }
+
+ if (optind >= argc && client || argc == 1)
+ {
+ usage();
+ return 1;
+ }
+
+ ACE_INET_Addr addr (server ? dstport : dstport + 1);
+
+ if (server)
+ {
+ Server server (addr);
+
+ ACE_Reactor::run_event_loop ();
+ }
+ else
+ {
+ if ((u_int) bufsz < sizeof (ACE_hrtime_t))
+ {
+ ACE_OS::printf("\nbufsz must be >= %d\n", sizeof (ACE_hrtime_t));
+ return 1;
+ }
+
+ ACE_INET_Addr remote_addr;
+
+ if (isdigit(argv[optind][0]))
+ {
+ if (remote_addr.set (dstport,
+ (ACE_UINT32) ACE_OS::inet_addr (argv[optind])) == -1)
+ {
+ ACE_ERROR ((LM_ERROR, "invalid IP address: %s\n", argv[optind]));
+ return 1;
+ }
+ }
+ else
+ {
+ if (remote_addr.set (dstport, argv[optind]) == -1)
+ {
+ ACE_ERROR ((LM_ERROR, "invalid IP address: %s\n", argv[optind]));
+ return 1;
+ }
+ }
+ optind++;
+
+ Client client (addr, remote_addr);
+
+ ACE_OS::printf("\nSending %d byte packets to %s:%d "
+ "with so_bufsz = %d\n\n",
+ bufsz, addr.get_host_name (), dstport, so_bufsz);
+
+ client.run ();
+ client.shutdown ();
+ }
+
+ return 0;
+}