diff options
Diffstat (limited to 'TAO/performance-tests/Thruput/COOL')
-rw-r--r-- | TAO/performance-tests/Thruput/COOL/Makefile | 133 | ||||
-rw-r--r-- | TAO/performance-tests/Thruput/COOL/README | 117 | ||||
-rw-r--r-- | TAO/performance-tests/Thruput/COOL/client.cpp | 292 | ||||
-rw-r--r-- | TAO/performance-tests/Thruput/COOL/server.cpp | 226 | ||||
-rw-r--r-- | TAO/performance-tests/Thruput/COOL/ttcp.idl | 36 | ||||
-rw-r--r-- | TAO/performance-tests/Thruput/COOL/ttcp_decl.h | 78 | ||||
-rw-r--r-- | TAO/performance-tests/Thruput/COOL/ttcp_i.cpp | 112 | ||||
-rw-r--r-- | TAO/performance-tests/Thruput/COOL/ttcp_i.h | 49 | ||||
-rw-r--r-- | TAO/performance-tests/Thruput/COOL/utils.cpp | 469 |
9 files changed, 1512 insertions, 0 deletions
diff --git a/TAO/performance-tests/Thruput/COOL/Makefile b/TAO/performance-tests/Thruput/COOL/Makefile new file mode 100644 index 00000000000..08735a2d8fd --- /dev/null +++ b/TAO/performance-tests/Thruput/COOL/Makefile @@ -0,0 +1,133 @@ +#---------------------------------------------------------------------------- +# $Id$ +# +# Makefile for the CHORUS COOL Cubit tests +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +IDL_SRC = ttcp.cpp ttcp.H sk_ttcp.C sk_ttcp.H + +SRC = $(IDL_SRC) ttcp_i.cpp server.cpp client.cpp utils.cpp + +SVR_OBJS = ttcp_i.o server.o ttcp.o utils.o + +CLT_OBJS = client.o ttcp.o utils.o + +LDLIBS = -lm -lOrb-mt -lposix4 + +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +#---------------------------------------------------------------------------- +# 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 + +#---------------------------------------------------------------------------- +# CHORUS related macros and target settings. +#---------------------------------------------------------------------------- + +CHORUS_BINDIR = $(CHORUS_ROOT)/bin +CHORUS_LIBDIR = $(CHORUS_ROOT)/lib +CHORUS_INCDIR = $(CHORUS_ROOT)/include + +CPPFLAGS += -I$(CHORUS_INCDIR) -I$(CHORUS_ROOT) +LDFLAGS += -L$(CHORUS_LIBDIR) -R $(CHORUS_LIBDIR) -L$(ACE)/ace +IDLFLAGS = --stub-header --stub-impl --skeleton-header --skeleton-impl --no-local --no-any --binding ttcp_sequence ttcp_sequence_i + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +all: $(IDL_SRC) server client + +$(IDL_SRC): ttcp.idl + $(CHORUS_BINDIR)/chic $(IDLFLAGS) ttcp.idl + -/bin/mv ttcp.C ttcp.cpp + +server: $(addprefix $(VDIR),$(SVR_OBJS)) + $(LINK.cc) -o server $(addprefix $(VDIR),$(SVR_OBJS)) $(LDFLAGS) $(ITIIOP) $(ITSRV) $(VLDLIBS) $(POSTLINK) + +client: $(addprefix $(VDIR),$(CLT_OBJS)) + $(LINK.cc) -o client $(addprefix $(VDIR),$(CLT_OBJS)) $(LDFLAGS) $(ITIIOP) $(ITCLT) $(VLDLIBS) $(POSTLINK) + +realclean: clean + -/bin/rm -rf ttcp.cpp ttcp.H sk_ttcp.C sk_ttcp.H server client + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +ttcp.o: ttcp.cpp ttcp.H \ + /project/doc/miniCOOL/minicool.r4.3/solaris2.5-CC-mt/include/corba/shortSeq.H \ + /project/doc/miniCOOL/minicool.r4.3/solaris2.5-CC-mt/include/corba/longSeq.H \ + /project/doc/miniCOOL/minicool.r4.3/solaris2.5-CC-mt/include/corba/doubleSeq.H \ + /project/doc/miniCOOL/minicool.r4.3/solaris2.5-CC-mt/include/corba/charSeq.H \ + /project/doc/miniCOOL/minicool.r4.3/solaris2.5-CC-mt/include/corba/octetSeq.H +sk_ttcp.o: sk_ttcp.C +ttcp_i.o: ttcp_i.cpp \ + $(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/Basic_Types.i \ + $(ACE_ROOT)/ace/OS.i \ + $(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 ttcp_i.h ttcp.H \ + /project/doc/miniCOOL/minicool.r4.3/solaris2.5-CC-mt/include/corba/cool.H \ + /project/doc/miniCOOL/minicool.r4.3/solaris2.5-CC-mt/include/corba/shortSeq.H \ + /project/doc/miniCOOL/minicool.r4.3/solaris2.5-CC-mt/include/corba/longSeq.H \ + /project/doc/miniCOOL/minicool.r4.3/solaris2.5-CC-mt/include/corba/doubleSeq.H \ + /project/doc/miniCOOL/minicool.r4.3/solaris2.5-CC-mt/include/corba/charSeq.H \ + /project/doc/miniCOOL/minicool.r4.3/solaris2.5-CC-mt/include/corba/octetSeq.H \ + ttcp_decl.h \ + $(ACE_ROOT)/ace/Profile_Timer.h \ + $(ACE_ROOT)/ace/Time_Value.h \ + $(ACE_ROOT)/ace/High_Res_Timer.h \ + $(ACE_ROOT)/ace/High_Res_Timer.i \ + $(ACE_ROOT)/ace/Profile_Timer.i +server.o: server.cpp \ + $(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/Basic_Types.i \ + $(ACE_ROOT)/ace/OS.i \ + $(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 ttcp_i.h ttcp.H \ + /project/doc/miniCOOL/minicool.r4.3/solaris2.5-CC-mt/include/corba/cool.H \ + /project/doc/miniCOOL/minicool.r4.3/solaris2.5-CC-mt/include/corba/shortSeq.H \ + /project/doc/miniCOOL/minicool.r4.3/solaris2.5-CC-mt/include/corba/longSeq.H \ + /project/doc/miniCOOL/minicool.r4.3/solaris2.5-CC-mt/include/corba/doubleSeq.H \ + /project/doc/miniCOOL/minicool.r4.3/solaris2.5-CC-mt/include/corba/charSeq.H \ + /project/doc/miniCOOL/minicool.r4.3/solaris2.5-CC-mt/include/corba/octetSeq.H \ + $(ACE_ROOT)/ace/Get_Opt.h \ + $(ACE_ROOT)/ace/Get_Opt.i sk_ttcp.H \ + sk_ttcp.C + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/TAO/performance-tests/Thruput/COOL/README b/TAO/performance-tests/Thruput/COOL/README new file mode 100644 index 00000000000..f227cfeea21 --- /dev/null +++ b/TAO/performance-tests/Thruput/COOL/README @@ -0,0 +1,117 @@ + TTCP Benchmark README file + +This directory contains a modified version of the TTCP benchmark that +uses the TAO ORB. TTCP is used to measure the throughput of COOL +for sending different data types. This code tests sequences of short, +long, octet, char, double, and richly-typed data such as a struct. + +Organization +------------ + +client.cpp Client main program +server.cpp Server main program +ttcp.cpp Client & Server side stub +ttcp.H Client & Server side stub header file +sk_ttcp.C Server skeleton implementation file +sk_ttcp.H Server skeleton implementation header file +ttcp_i.cpp Implementation of the interface +ttcp_i.h Header for the implementation +utils.cpp Utilities to calculate throughput +ttcp_decl.h Common declarations + +Results +------- +Throughput results are displayed on stdout. + +Running the test +----------------- + Server + ------ + Usage: + server [COOL options] [Common options] + + [COOL options] ** these are required ** + cool-tcp://<THIS_HOSTNAME>:<THIS_HOST_PORT> -cool-tcp -cool-iiop + + THIS_HOSTNAME : the name of the host that the server will be running on. This is useful + if you want to specifya different interface (e.g. ATM, 100Mbit Ethernet) + + THIS_HOST_PORT: is the port number at which the server will start the high + priority servant. The low priority servant will be created at + (THIS_HOST_PORT+1). + + [Common options]: + -l ## length of bufs read from or written to network (default 8192) + -v verbose: print more statistics + -d ## set debug level + -f X format for rate: k,K = kilo{bit,byte}; m,M = mega; g,G = giga + -L ## Output file name to store results + + Example: + + server cool-tcp://tango.cs.wustl.edu:3000 -cool-tcp -cool-iiop -d 1 + + The Output might look like this: + stringified obj reference = IOR:000000000000001649444C3A747463705F73657175656E63653A312E3000000000000002000000000000004900010000000000103132382E3235322E3136352E313430000BB80000000000290000000001000000010000001C0073193B00000002EFFFED98000000000000000A80FCA58C00000BB8000000434F4F4C000000290000000001000000010000001C0073193B00000002EFFFED98000000000000000A80FCA58C00000BB8 + Entering boa->run (). + + + Client + ------ + + Usage: + client -cool-tcp -cool-iiop [Common options] + + [Common options]: + -l ## length of bufs read from or written to network (default 8192) + -v verbose: print more statistics + -d ## debug level + -f X format for rate: k,K = kilo{bit,byte}; m,M = mega; g,G = giga + -h ## Remote host to send data to + -p ## Port number" + -S ## Total Data Size to be sent + -L ## Output file name to store results + -q <type> Send Sequence: Enumeration for various data types: + s = short, l = long, d = double, c = char + o = octet, S = BinStruct + + Example: + + # The following example will send 10Mb of data, using a megabyte rate, + in 1024 byte chunks, to host tango.cs.wustl.edu, to port 3000, and will send shorts + + client -cool-tcp -cool-iiop -S 10240000 -f m -l 1024 -h tango.cs.wustl.edu -p 3000 -q s + + The Output might look like this: + + Composed IOR string as: cool-tcp://tango.cs.wustl.edu:3000 + data size = 10240000, buflen = 1024, nbuf = 10000 + ttcp-t: 10240000 bytes in 2.81 real seconds = 27.82 Mbit/sec +++ + ttcp-t: 10000 Server Method calls, msec/call = 0.29, calls/sec = 3561.29 + ttcp-r: 10236928 bytes in 2.81 real seconds = 3560.03 KB/sec +++ + ttcp-r: 9993 Server Method calls, msec/call = 0.29, calls/sec = 3558.60 + ttcp-t: 176224.1user -1.-2674sys 0:02real 6261769% 0i+0d 101622maxrss -268440216+-277460652pf 10002+458757csw + ttcp-r: -268441649.-103user 728.0sys 0:02real -194852% 0i+0d 420maxrss -280679408+0pf -268441576+-277738728csw + + +Compiling +--------- + +Setup the CHORUS COOL environment variables before compiling, the +following is an example. You would typically want this in the shells' +resource file (e.g. .cshrc.mine). The example provided is for a C +shell. + + setenv CHORUS_ROOT /project/doc/miniCOOL/minicool.r4.3/solaris2.5-CC-mt + set path = ($path /project/doc/miniCOOL/minicool.r4.3/solaris2.5-CC-mt/bin) + setenv LD_LIBRARY_PATH /project/doc/miniCOOL/minicool.r4.3/solaris2.5-CC-mt/lib:$LD_LIBRARY_PATH + setenv MANPATH /project/doc/miniCOOL/minicool.r4.3/solaris2.5-CC-mt/man:$MANPATH + +Makefiles are provided. Use make to compile. + +You can either run the server in the background in the same window as +the client or open a separate window for the client and server. + + +-Sergio Flores-Gaitan +(sergio@cs.wustl.edu)
\ No newline at end of file diff --git a/TAO/performance-tests/Thruput/COOL/client.cpp b/TAO/performance-tests/Thruput/COOL/client.cpp new file mode 100644 index 00000000000..29d8906ea0c --- /dev/null +++ b/TAO/performance-tests/Thruput/COOL/client.cpp @@ -0,0 +1,292 @@ +// $Id$ + +// ============================================================================ +// +// = Chorus COOL tests +// Throughput measurement using the TTCP benchmark adapted to work using COOL +// +// = FILENAME +// client.cpp +// +// Main program for the client +// +// = AUTHOR +// Aniruddha Gokhale +// Sergio Flores Ported code to use Chorus COOL ORB +// +// ============================================================================ + +#include <iostream.h> +#include <fstream.h> + +#include "ace/ACE.h" +#include "ace/Get_Opt.h" +#include "ttcp.H" +#include "ttcp_decl.h" + +#include "api/api.H" + +ACE_RCSID(COOL, client, "$Id$") + +int print_usage (void); + +char Usage[] = + "Usage: client -cool-tcp -cool-iiop [Common options] \n" + "[Common options]:\n" + " -l ## length of bufs read from or written to network (default 8192)\n" + " -v verbose: print more statistics\n" + " -d ## debug level\n" + " -f X format for rate: k,K = kilo{bit,byte}; m,M = mega; g,G = giga\n" + " -h ## Remote host to send data to\n" + " -p ## Port number" + " -L ## Output file name to store results\n" + " -S ## Total Data Size to be sent\n" + " -q <type> Send Sequence: Enumeration for various data types:\n" + " s = short, l = long, d = double, c = char\n" + " o = octet, S = BinStruct \n"; + +CORBA::Long trans = 1; // we are a client - used for debugging purposes +CORBA::Long buflen = 8 * 1024; // length of buffer, default 8,192 bytes +char *buf; // ptr to dynamic buffer +CORBA::Long nbuf; // number of buffers to send in sinkmode +CORBA::Short port = 3000; // default TCP port number +char *host = "localhost"; // ptr to name of host +CORBA::Long verbose = 0; // 0=print basic info, 1=print cpu + // rate, proc resource usage. +CORBA::Char fmt = 'K'; // output + // format:k=kilobits,K=kilobytes, m = megabits, + // M = megabytes, g = gigabits, G = gigabytes +CORBA::String title = 0; // title of file to gather statistics +char stats[128]; // gathering the statistics +unsigned long srcDataSize; // Total amount of source data +unsigned long nbytes; // bytes on net +unsigned long numCalls; // # of I/O system calls +double cput, realt; // user, real time (seconds) +unsigned long dt; // data type + +u_int debug_level = 0; + +// declare variables for various message types +ttcp_sequence::ShortSeq *sseq; +ttcp_sequence::LongSeq *lseq; +ttcp_sequence::OctetSeq *oseq; +ttcp_sequence::DoubleSeq *dseq; +ttcp_sequence::CharSeq *cseq; +ttcp_sequence::StructSeq *Sseq; + +int +main (int argc, char *argv[]) +{ + + int c; + CORBA_ORB_ptr orb_ptr; // underlying ORB + CORBA::Object_ptr objref = CORBA::Object::_nil(); // object reference + ttcp_sequence_ptr ttcp_seq = 0; // obj reference to TTCP object + CORBA::Environment env; // environment + CORBA::String str; // holds the IOR + + fstream iorfile; + + // parse the arguments + ACE_Get_Opt get_opt (argc, argv, "d:vh:p:f:l:L:S:q:", 3); // Command line options + debug_level = 0; + while ((c = get_opt ()) != -1) + { + switch (c) + { + case 'h': + host = ACE_OS::strdup (get_opt.optarg); + break; + case 'L': + title = ACE_OS::strdup (get_opt.optarg); + break; + case 'p': + port = ACE_OS::atoi (get_opt.optarg); + break; + case 'd': + debug_level = ACE_OS::atoi (get_opt.optarg); + if (debug_level > 10) + debug_level = 10; + break; + case 'l': + buflen = ACE_OS::atoi (get_opt.optarg); + break; + case 'v': + verbose = 1; + break; + case 'f': + fmt = *get_opt.optarg; + break; + case 'S': /* total source data to send. */ + srcDataSize = ACE_OS::atoi (get_opt.optarg); + break; + case 'q': /* Send sequence of desired data type */ + switch(*get_opt.optarg){ + case 's': + dt = SEND_SHORT; + break; + case 'l': + dt = SEND_LONG; + break; + case 'd': + dt = SEND_DOUBLE; + break; + case 'c': + dt = SEND_CHAR; + break; + case 'o': + dt = SEND_OCTET; + break; + case 'S': + dt = SEND_STRUCT; + break; + case 'C': + dt = SEND_COMPOSITE; + break; + } + break; + default: + return print_usage (); + } + } + + // + // Transmitter + // + + // get a handle to the ORB + orb_ptr = CORBA_ORB_init (argc, argv, 0, env); + if (env.exception () != 0) + { + ACE_DEBUG ((LM_DEBUG, "ORB initialization\n")); + //env.print_exception ("ORB initialization", stdout); + return -1; + } + + // allocate storage to read the IOR string + str = CORBA::string_alloc (500); + + sprintf (str, "cool-tcp://%s:%d", host, port); + + ACE_DEBUG ((LM_DEBUG, "Composed IOR string as: %s\n" , str)); + + COOL::EOABindingData bindingData (str); + ttcp_seq = ttcp_sequence::_bind(bindingData, env); + + CORBA::string_free (str); + + if (!CORBA::is_nil (ttcp_seq)) + { + // the number of iterations is based on the total data size and the + // individual buffer size sent + nbuf = srcDataSize/buflen; + ACE_DEBUG ((LM_DEBUG, "data size = %d, buflen = %d, nbuf = %d\n", + srcDataSize, buflen, nbuf)); + + // + // Prepare the Message to be sent + // + + + // first allocate a buffer of the desired size and alignment + errno = 0; + if ((buf = (char *) ACE_OS::malloc (buflen)) == (char *) NULL) + err ("malloc"); + + // fill the buffer with the data type to be sent + FillPattern (buf, buflen, dt); + + // + // Start the timers on the client and server sides + // + + prep_timer (); // start our time + ttcp_seq->start_timer (env); // ask the server to start its timer + if (env.exception () != 0) + { + ACE_DEBUG ((LM_DEBUG, "start_timer operation\n")); + //env.print_exception ("start_timer operation", stdout); + return -1; + } + +#if defined (USE_QUANTIFY) + /* start recording quantify data from here */ + quantify_clear_data (); + quantify_start_recording_data (); +#endif + // send the same buffer nbuf times + while (nbuf--) + { + switch (dt){ + case SEND_SHORT: + ttcp_seq->sendShortSeq (*sseq, env); + nbytes += sseq->length () * sizeof (CORBA::Short); + break; + case SEND_LONG: + ttcp_seq->sendLongSeq (*lseq, env); + nbytes += lseq->length () * sizeof (CORBA::Long); + break; + case SEND_OCTET: + ttcp_seq->sendOctetSeq (*oseq, env); + nbytes += oseq->length () * sizeof (CORBA::Octet); + break; + case SEND_DOUBLE: + ttcp_seq->sendDoubleSeq (*dseq, env); + nbytes += dseq->length () * sizeof (CORBA::Double); + break; + case SEND_CHAR: + ttcp_seq->sendCharSeq (*cseq, env); + nbytes += cseq->length () * sizeof (CORBA::Char); + break; + case SEND_STRUCT: + ttcp_seq->sendStructSeq (*Sseq, env); + nbytes += Sseq->length () * sizeof (BinStruct); + break; + } + numCalls++; // nbytes and numCalls are used in the thruput + // measurement + if (env.exception () != 0) + { + ACE_DEBUG ((LM_DEBUG, "send operation\n")); + //env.print_exception ("send operation", stdout); + return -1; + } + } +#if defined (USE_QUANTIFY) + quantify_stop_recording_data(); +#endif + // + // Stop the timer + // + // stop the timer on the server side + ttcp_seq->stop_timer (env); + if (env.exception () != 0) + { + ACE_DEBUG ((LM_DEBUG, "stop_timer operation\n")); + //env.print_exception ("stop_timer operation", stdout); + return -1; + } + // stop our timer + (void) read_timer (stats, sizeof (stats)); + + // print results + PrintStats(); + } + else + { + ACE_ERROR ((LM_ERROR, "error: objref is nil\n")); + } + + + CORBA::release (ttcp_seq); + CORBA::release (objref); + + return (0); +} + +int print_usage (void) +{ + ACE_ERROR ((LM_ERROR, "Usage error\n")); + ACE_ERROR ((LM_ERROR, "%s\n", Usage)); + return -1; +} diff --git a/TAO/performance-tests/Thruput/COOL/server.cpp b/TAO/performance-tests/Thruput/COOL/server.cpp new file mode 100644 index 00000000000..499269a542b --- /dev/null +++ b/TAO/performance-tests/Thruput/COOL/server.cpp @@ -0,0 +1,226 @@ +// $Id$ + +// ============================================================================ +// +// = Chorus COOL tests +// Throughput measurement using the TTCP benchmark adapted to work using +// Chorus COOL +// +// = FILENAME +// server.cpp +// +// = AUTHOR +// Aniruddha Gokhale +// Sergio Flores Ported from TAO +// +// ============================================================================ + +#include <iostream.h> +#include <fstream.h> + +#include "ace/ACE.h" +#include "ace/Get_Opt.h" + +#include "ttcp_i.h" + +#include <api/binding.H> +#include <api/api.H> +#include <api/coolThreadPool.H> +#include <corba/eoa.H> +#include <corba/eorb.H> + +#include "ttcp.H" +#include "sk_ttcp.H" +#include "sk_ttcp.C" + +ACE_RCSID(COOL, server, "$Id$") + +char Usage[] = "\ +Usage: server [COOL options] [Common options] \n\ + [COOL options] ** these are required ** \n\ + cool-tcp://<THIS_HOSTNAME>:<THIS_HOST_PORT> -cool-tcp -cool-iiop \n\n\ + THIS_HOSTNAME : the name of the host that the server will be running on. \n\ + This is useful if you want to specify a different interface (e.g. ATM, \n\ + 100Mbit Ethernet)\n\n\ + THIS_HOST_PORT: is the port number at which the server will start the high\n\ + priority servant. The low priority servant will be created at\n\ + (THIS_HOST_PORT+1).\n\n\ + [Common options]:\n\ + -l ## length of bufs read from or written to network (default 8192)\n\ + -v verbose: print more statistics\n\ + -d ## set debug level \n\ + -f X format for rate: k,K = kilo{bit,byte}; m,M = mega; g,G = giga\n\ + -L ## Output file name for the data type used\n\n\ +"; + +CORBA::Long trans = 0; // we are the receiver +CORBA::Long buflen = 8 * 1024; // length of buffer +CORBA::Char *buf; // ptr to dynamic buffer +CORBA::Long nbuf; // number of buffers to send in sinkmode +CORBA::Long verbose = 0; // 0=print basic info, 1=print cpu rate, proc + // resource usage. +CORBA::Char fmt = 'K'; // output format:k=kilobits,K=kilobytes, m = + // megabits, M = megabytes, g = gigabits, G = + // gigabytes +u_int debug_level = 0; + +CORBA::String title = 0; // results filename + +CORBA::Char stats[128]; // gathering the statistics +CORBA::ULong srcDataSize; // Total amount of source data +CORBA::ULong nbytes; // bytes on net +CORBA::ULong numCalls; // # of I/O system calls +CORBA::Double cput, realt; // user, real time (seconds) +CORBA::ULong dt; // data type + +/* declare struct variables for various message types */ +ttcp_sequence::ShortSeq *sseq; +ttcp_sequence::LongSeq *lseq; +ttcp_sequence::OctetSeq *oseq; +ttcp_sequence::DoubleSeq *dseq; +ttcp_sequence::CharSeq *cseq; +ttcp_sequence::StructSeq *Sseq; + +// main program - Driver +int +main (int argc, char **argv) +{ + + int c; // option + CORBA::Environment env; // environment + CORBA_ORB_ptr orb_ptr; // handle to the ORB + CORBA_BOA_ptr oa_ptr; // Object adapter + CORBA::String str; // for stringified representation of the object reference + ttcp_sequence_i my_ttcp_i ("TTCP_IIOP_test"); // instance of the target object + ttcp_sequence_ptr my_ttcp; + + COOL::EOA::bind(argv[1], env); + if (env.exception() != 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "Impossible to bind the ORB to the description:%s\n", + argv[1]), -1); + } + + // initialize the underlying ORB and get a handle to it + orb_ptr = CORBA_ORB_init (argc, argv, 0, env); + if (env.exception () != 0) + { + ACE_DEBUG ((LM_ERROR, "ORB_init failed..\n")); + CORBA::SystemException* ex; + + ex = CORBA::SystemException::_narrow(env.exception()); + if (ex) + { + CORBA::String_var msg = ex->message(); + fprintf(stderr, "%s.\n", (const char*) msg); + } + else + { + fprintf(stderr, "Unknown user exception.\n"); + } + return -1; + } + + // now get a handle to the object adapter + oa_ptr = orb_ptr->OA_init (argc, argv, 0, env); + if (env.exception () != 0) + { + CORBA::SystemException* ex; + + ex = CORBA::SystemException::_narrow(env.exception()); + if (ex) + { + CORBA::String_var msg = ex->message(); + fprintf(stderr, "%s.\n", (const char*) msg); + } + else + { + fprintf(stderr, "Unknown user exception.\n"); + } + ACE_ERROR_RETURN ((LM_ERROR, + " (%P|%t) Unable to initialize the POA.\n"), + -1); + } + + // for parsing the arguments + ACE_Get_Opt get_opt (argc, argv, "l:vd:f:L:", 2, 1); + debug_level = 0; + while ((c = get_opt ()) != -1) + { + switch (c) + { + case 'v': + verbose = 1; + break; + case 'L': + // title of output file that stores result + title = ACE_OS::strdup (get_opt.optarg); + break; + case 'd': + // debugging level + debug_level = ACE_OS::atoi (get_opt.optarg); + if (debug_level > 10) + debug_level = 10; + break; + case 'f': + // output format i.e., Mbps, Kbps, etc + fmt = *get_opt.optarg; + break; + default: + ACE_ERROR ((LM_ERROR, "Usage error\n")); + ACE_ERROR ((LM_ERROR, "%s\n", Usage)); + return -1; + } + } + + // + // Receiver + // + + COOL::EOABindingData bindingData; + + COOL_bind (my_ttcp_i, my_ttcp, bindingData, env); + + if (env.exception ()) + { + ACE_DEBUG ((LM_ERROR, "Bind failed.\n")); + return -1; + } + + if (debug_level > 0) + { + // get a stringified representation of the object reference created above + str = orb_ptr->object_to_string (my_ttcp, env); + if (env.exception() != 0) + { + CORBA::SystemException* ex; + + ex = CORBA::SystemException::_narrow(env.exception()); + if (ex) + { + CORBA::String_var msg = ex->message(); + fprintf(stderr, "%s.\n", (const char*) msg); + } + else + { + fprintf(stderr, "Unknown user exception.\n"); + } + return -1; + } + ACE_DEBUG ((LM_DEBUG, "stringified obj reference = %s\n", str)); + } + +#if defined (USE_QUANTIFY) + // gather profile data + quantify_clear_data(); + quantify_start_recording_data(); +#endif + + // Handle requests for this object until we're killed, or one of the + // methods asks us to exit. + ACE_DEBUG ((LM_DEBUG, "Entering boa->run ().\n")); + oa_ptr->run (); + + return 0; +} diff --git a/TAO/performance-tests/Thruput/COOL/ttcp.idl b/TAO/performance-tests/Thruput/COOL/ttcp.idl new file mode 100644 index 00000000000..bccdf4e374e --- /dev/null +++ b/TAO/performance-tests/Thruput/COOL/ttcp.idl @@ -0,0 +1,36 @@ +/* -*- C++ -*- */ +// $Id$ + +struct BinStruct +{ + short s; + char c; + long l; + octet o; + double d; + // octet pad[8]; // to make it 32 bytes + // commented out until IDL support for arrays is added +}; + +// Richly typed data +interface ttcp_sequence +{ + typedef sequence<short> ShortSeq; + typedef sequence<long> LongSeq; + typedef sequence<double> DoubleSeq; + typedef sequence<char> CharSeq; + typedef sequence<octet> OctetSeq; + typedef sequence<BinStruct> StructSeq; + + + // Routines to send sequences of various data types + oneway void sendShortSeq (in ShortSeq ttcp_seq); + oneway void sendLongSeq (in LongSeq ttcp_seq); + oneway void sendDoubleSeq (in DoubleSeq ttcp_seq); + oneway void sendCharSeq (in CharSeq ttcp_seq); + oneway void sendOctetSeq (in OctetSeq ttcp_seq); + oneway void sendStructSeq (in StructSeq ttcp_seq); + + oneway void start_timer (); + oneway void stop_timer (); +}; diff --git a/TAO/performance-tests/Thruput/COOL/ttcp_decl.h b/TAO/performance-tests/Thruput/COOL/ttcp_decl.h new file mode 100644 index 00000000000..57440e13fc8 --- /dev/null +++ b/TAO/performance-tests/Thruput/COOL/ttcp_decl.h @@ -0,0 +1,78 @@ +// $Id$ + + +/* + * T T C P Header File + * + */ + +/* This file includes all the declarations and prototypes */ + +#ifndef _TTCP_DECL_H_ +#define _TTCP_DECL_H_ + +#include "ace/OS.h" +#include "ace/Profile_Timer.h" + +/* File to be included if Quantify is to be used */ +#if defined (USE_QUANTIFY) +#include <quantify.h> +#endif + + +/* define the data types to be sent */ +#define SEND_SHORT ((CORBA::ULong)(1)) +#define SEND_LONG ((CORBA::ULong)(2)) +#define SEND_CHAR ((CORBA::ULong)(3)) +#define SEND_OCTET ((CORBA::ULong)(4)) +#define SEND_DOUBLE ((CORBA::ULong)(5)) +#define SEND_STRUCT ((CORBA::ULong)(6)) +#define SEND_COMPOSITE ((CORBA::ULong)(7)) + +/************** +// Prototypes +***************/ +int err (char *s); +void mes (CORBA::Char *s); +CORBA::String outfmt (CORBA::Double b); +void prep_timer (void); +CORBA::Double read_timer (char *str, CORBA::Long len); +void prusage (register struct rusage *r0, struct rusage *r1, struct timeval *e, struct timeval *b, char *outp); +void tvadd (struct timeval *tsum, struct timeval *t0, struct timeval *t1); +void tvsub (struct timeval *tdiff, struct timeval *t1, struct timeval *t0); +void psecs (CORBA::Long l, register char *cp); +void delay (CORBA::Long us); +void FillPattern (register char *cp, register CORBA::Long bufLen, CORBA::ULong dt); +void PrintStats (void); + +/* Global variables defined here as extern */ +extern ACE_Svc_Export CORBA::Long trans; // whether we are transmitter + // or receiver +extern ACE_Svc_Export CORBA::Long buflen; /* length of buffer */ +extern ACE_Svc_Export char *buf; /* ptr to dynamic buffer */ +extern ACE_Svc_Export CORBA::Long nbuf; /* number of buffers to send in sinkmode */ +extern ACE_Svc_Export CORBA::Short port; /* TCP port number */ +extern ACE_Svc_Export char *host; /* ptr to name of host */ +extern ACE_Svc_Export CORBA::Long verbose; /* 0=print basic info, 1=prCORBA::Long cpu rate, proc + * resource usage. */ +extern ACE_Svc_Export CORBA::Char fmt; /* output format:k=kilobits,K=kilobytes, + * m = megabits, M = megabytes, + * g = gigabits, G = gigabytes */ +extern ACE_Svc_Export char *title; + +extern ACE_Svc_Export char stats[128]; +extern ACE_Svc_Export CORBA::ULong srcDataSize; /* Total amount of source data */ +extern ACE_Svc_Export CORBA::ULong nbytes; /* bytes on net */ +extern ACE_Svc_Export CORBA::ULong numCalls; /* # of I/O system calls */ +extern ACE_Svc_Export CORBA::Double cput, realt; /* user, real time (seconds) */ +extern ACE_Svc_Export CORBA::ULong dt; + +/* declare struct variables for various message types */ +extern ACE_Svc_Export ttcp_sequence::ShortSeq *sseq; +extern ACE_Svc_Export ttcp_sequence::LongSeq *lseq; +extern ACE_Svc_Export ttcp_sequence::OctetSeq *oseq; +extern ACE_Svc_Export ttcp_sequence::DoubleSeq *dseq; +extern ACE_Svc_Export ttcp_sequence::CharSeq *cseq; +extern ACE_Svc_Export ttcp_sequence::StructSeq *Sseq; + +#endif diff --git a/TAO/performance-tests/Thruput/COOL/ttcp_i.cpp b/TAO/performance-tests/Thruput/COOL/ttcp_i.cpp new file mode 100644 index 00000000000..9a6af6b6b9c --- /dev/null +++ b/TAO/performance-tests/Thruput/COOL/ttcp_i.cpp @@ -0,0 +1,112 @@ +// $Id$ + +//#include <iostream.h> +#include "ace/ACE.h" +#include "ace/streams.h" +#include "ttcp_i.h" +#include "ttcp_decl.h" + +ACE_RCSID(COOL, ttcp_i, "$Id$") + +/* the ttcp_i class implementation */ +ttcp_sequence_i::ttcp_sequence_i (const char *obj_name) +{ + this->nbytes_ = 0; + numCalls = 0; +} + +void +ttcp_sequence_i::start_timer (CORBA::Environment &IT_env) +{ + ACE_UNUSED_ARG (IT_env); + this->nbytes_ = 0; + ::prep_timer (); +} + +void +ttcp_sequence_i::stop_timer (CORBA::Environment &IT_env) +{ + ACE_UNUSED_ARG (IT_env); + + (void) ::read_timer (stats, sizeof (stats)); + ::nbytes = this->nbytes_; + ::PrintStats(); + // reset + this->nbytes_ = 0; + numCalls = 0; +#if defined (USE_QUANTIFY) + quantify_stop_recording_data(); + ACE_Service_Config::end_reactor_event_loop(); + cerr << "*********** just before exiting " << endl; +#endif +#if defined (USE_PURIFY) + ACE_Service_Config::end_reactor_event_loop(); + cerr << "*********** just before exiting " << endl; +#endif +} + +void +ttcp_sequence_i::sendShortSeq (const ttcp_sequence::ShortSeq& ttcp_seq, + CORBA::Environment &IT_env) +{ + ACE_UNUSED_ARG (IT_env); + numCalls++; + this->nbytes_ += ttcp_seq.length()*sizeof(CORBA::Short); +} + +void +ttcp_sequence_i::sendLongSeq (const ttcp_sequence::LongSeq& ttcp_seq, + CORBA::Environment &IT_env) +{ + ACE_UNUSED_ARG (IT_env); + numCalls++; + this->nbytes_ += ttcp_seq.length()*sizeof(CORBA::Long) ; +} + +void +ttcp_sequence_i::sendOctetSeq (const ttcp_sequence::OctetSeq& ttcp_seq, + CORBA::Environment &IT_env) +{ + ACE_UNUSED_ARG (IT_env); + numCalls++; + this->nbytes_ += ttcp_seq.length()*sizeof(CORBA::Octet) ; +} + +void +ttcp_sequence_i::sendDoubleSeq (const ttcp_sequence::DoubleSeq& ttcp_seq, + CORBA::Environment &IT_env) +{ + ACE_UNUSED_ARG (IT_env); + numCalls++; + this->nbytes_ += ttcp_seq.length()*sizeof(CORBA::Double) ; +} + +void +ttcp_sequence_i::sendCharSeq (const ttcp_sequence::CharSeq& ttcp_seq, + CORBA::Environment &IT_env) +{ + ACE_UNUSED_ARG (IT_env); + numCalls++; + this->nbytes_ += ttcp_seq.length()*sizeof(CORBA::Char) ; +} + +void +ttcp_sequence_i::sendStructSeq (const ttcp_sequence::StructSeq& ttcp_seq, + CORBA::Environment &IT_env) +{ + ACE_UNUSED_ARG (IT_env); + numCalls++; + this->nbytes_ += ttcp_seq.length()*sizeof(BinStruct) ; +#ifdef DEBUG + // cout << "Bytes received so far = " << this->nbytes_ << endl; +#endif +} + + + + + + + + + diff --git a/TAO/performance-tests/Thruput/COOL/ttcp_i.h b/TAO/performance-tests/Thruput/COOL/ttcp_i.h new file mode 100644 index 00000000000..92743612475 --- /dev/null +++ b/TAO/performance-tests/Thruput/COOL/ttcp_i.h @@ -0,0 +1,49 @@ +// $Id$ + +// ============================================================================ +// +// = COOL tests +// Throughput measurement using the TTCP benchmark adapted to work using COOL +// +// = FILENAME +// ttcp_i.h +// +// = AUTHOR +// Aniruddha Gokhale +// Sergio Flores-Gaitan Ported to COOL +// +// ============================================================================ + +#if !defined (TTCP_I_H) +#define TTCP_I_H + +#include "ttcp.H" + +class ttcp_sequence_i +{ +public: + ttcp_sequence_i (const char *obj_name = 0); + + virtual void sendShortSeq (const ttcp_sequence::ShortSeq& ttcp_seq, + CORBA::Environment &IT_env); + virtual void sendLongSeq (const ttcp_sequence::LongSeq& ttcp_seq, + CORBA::Environment &IT_env); + virtual void sendDoubleSeq (const ttcp_sequence::DoubleSeq& ttcp_seq, + CORBA::Environment &IT_env); + virtual void sendCharSeq (const ttcp_sequence::CharSeq& ttcp_seq, + CORBA::Environment &IT_env); + virtual void sendStructSeq (const ttcp_sequence::StructSeq& ttcp_seq, + CORBA::Environment &IT_env); + virtual void sendOctetSeq (const ttcp_sequence::OctetSeq& ttcp_seq, + CORBA::Environment &IT_env); + + /* Routines to calculate the time required to transfer */ + virtual void start_timer (CORBA::Environment &IT_env); + virtual void stop_timer (CORBA::Environment &IT_env); + +private: + unsigned long nbytes_; +}; + +#endif // defined (TTCP_I_H) + diff --git a/TAO/performance-tests/Thruput/COOL/utils.cpp b/TAO/performance-tests/Thruput/COOL/utils.cpp new file mode 100644 index 00000000000..7894658d5c7 --- /dev/null +++ b/TAO/performance-tests/Thruput/COOL/utils.cpp @@ -0,0 +1,469 @@ +// $Id$ + +// ============================================================================ +// +// = TAO tests +// Throughput measurement using the TTCP benchmark adapted to work using TAO +// +// = FILENAME +// utils.cpp +// +// = AUTHOR +// Aniruddha Gokhale +// +// ============================================================================ + +// This file has all the helper functions that do the computation of +// throughput, system time used, user time, etc based on data collected. + +#include "ttcp.H" +#include "ttcp_decl.h" + +ACE_RCSID(COOL, utils, "$Id$") + +// the error function. +// displays the error message and exits +int err (char * s) +{ + ACE_OS::fprintf (stderr, "ttcp%s: ", trans ? "-t" : "-r"); + ACE_OS::perror (s); + ACE_OS::fprintf (stderr, "errno=%d\n", errno); + return -1; +} + +// prints a message indicating if it is a transmitter or a receiver +void mes (CORBA::String s) +{ + ACE_OS::fprintf (stderr, "ttcp%s: %s\n", trans ? "-t" : "-r", s); +} + +// does the formatting for the desired units in which the result is to be +// displayed +CORBA::String +outfmt (CORBA::Double b) +{ + static char obuf[50]; + switch (fmt) + { + case 'G': + ACE_OS::sprintf (obuf, "%.2f GB", b / 1024.0 / 1024.0 / 1024.0); + break; + default: + case 'K': + ACE_OS::sprintf (obuf, "%.2f KB", b / 1024.0); + break; + case 'M': + ACE_OS::sprintf (obuf, "%.2f MB", b / 1024.0 / 1024.0); + break; + case 'g': + ACE_OS::sprintf (obuf, "%.2f Gbit", b * 8.0 / 1024.0 / 1024.0 / 1024.0); + break; + case 'k': + ACE_OS::sprintf (obuf, "%.2f Kbit", b * 8.0 / 1024.0); + break; + case 'm': + ACE_OS::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 */ + +/* + * P R E P _ T I M E R + */ +// this is in fact the internals of the "start_timer" operation +void +prep_timer (void) +{ + 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; + + + ACE_OS::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 + * + */ +// This implements the internals of the "stop_timer" method +double +read_timer (char *str, CORBA::Long len) +{ + struct itimerval itimedol; + struct rusage ru1; + struct timeval td; + struct timeval tend, tstart; + char line[132]; + + ACE_OS::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); +} + +// prints the rusage stats +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); + ACE_OS::sprintf (outp, "%d.%01d", tdiff.tv_sec, tdiff.tv_usec / 100000); + END (outp); + break; + + case 'S': + tvsub (&tdiff, &r1->ru_stime, &r0->ru_stime); + ACE_OS::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': + ACE_OS::sprintf (outp, "%d%%", (int) (t * 100 / ((ms ? ms : 1)))); + END (outp); + break; + +#if !defined(SYSV) + case 'W': + i = r1->ru_nswap - r0->ru_nswap; + ACE_OS::sprintf (outp, "%d", i); + END (outp); + break; + + case 'X': + ACE_OS::sprintf (outp, "%d", t == 0 ? 0 : (r1->ru_ixrss - r0->ru_ixrss) / t); + END (outp); + break; + + case 'D': + ACE_OS::sprintf (outp, "%d", t == 0 ? 0 : + (r1->ru_idrss + r1->ru_isrss - (r0->ru_idrss + r0->ru_isrss)) / t); + END (outp); + break; + + case 'K': + ACE_OS::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': + ACE_OS::sprintf (outp, "%d", r1->ru_maxrss / 2); + END (outp); + break; + + case 'F': + ACE_OS::sprintf (outp, "%d", r1->ru_majflt - r0->ru_majflt); + END (outp); + break; + + case 'R': + ACE_OS::sprintf (outp, "%d", r1->ru_minflt - r0->ru_minflt); + END (outp); + break; + + case 'I': + ACE_OS::sprintf (outp, "%d", r1->ru_inblock - r0->ru_inblock); + END (outp); + break; + + case 'O': + ACE_OS::sprintf (outp, "%d", r1->ru_oublock - r0->ru_oublock); + END (outp); + break; + case 'C': + ACE_OS::sprintf (outp, "%d+%d", r1->ru_nvcsw - r0->ru_nvcsw, + r1->ru_nivcsw - r0->ru_nivcsw); + END (outp); + break; +#endif /* !SYSV */ + } + } + *outp = '\0'; +} + +// adds two "timeval" structures +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; +} + +// finds difference between two timevals +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; +} + +// print in seconds +void +psecs (CORBA::Long l, register char *cp) +{ + register int i; + + i = l / 3600; + if (i) + { + ACE_OS::sprintf (cp, "%d:", i); + END (cp); + i = l % 3600; + ACE_OS::sprintf (cp, "%d%d", (i / 60) / 10, (i / 60) % 10); + END (cp); + } + else + { + i = l; + ACE_OS::sprintf (cp, "%d", i / 60); + END (cp); + } + i %= 60; + *cp++ = ':'; + ACE_OS::sprintf (cp, "%d%d", i / 10, i % 10); +} + +// generate the specified delay in microseconds +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); +} + +// fill up a buffer with a data type that we want to send +void +FillPattern (register char *cp, register CORBA::Long bufLen, CORBA::ULong dt) +{ + unsigned long + num, i; + + switch(dt){ + case SEND_SHORT: + { + register short *SeqPtr = (short *)cp; + num = bufLen/sizeof(short); + for (i=0; i < num; i++) + SeqPtr[i] = (short)lrand48(); + sseq = new ttcp_sequence::ShortSeq(num,num, SeqPtr); + } + break; + case SEND_LONG: + { + register long *SeqPtr = (long *)cp; + num = bufLen/sizeof(long); + for (i=0; i < num; i++) + SeqPtr[i] = lrand48(); + lseq = new ttcp_sequence::LongSeq(num, num, SeqPtr); + } + break; + case SEND_DOUBLE: + { + register double *SeqPtr = (double *)cp; + num = bufLen/sizeof(double); + for (i=0; i < num; i++) + SeqPtr[i] = drand48(); + dseq = new ttcp_sequence::DoubleSeq(num, num, SeqPtr); + } + break; + case SEND_CHAR: + { + register CORBA::Char *SeqPtr = (CORBA::Char *)cp; + register char c = 0; + num = bufLen/sizeof(char); + for(i=0; i < num; i++){ + while (!isprint(c & 0x7f)) + c++; + SeqPtr[i] = (c++ & 0x7f); + } + cseq = new ttcp_sequence::CharSeq(num, num, SeqPtr); + } + break; + case SEND_STRUCT: + { + register BinStruct *SeqPtr = (BinStruct *)cp; + register char c = 0; + num = bufLen/sizeof(BinStruct); + for (i=0; i < num; i++){ + SeqPtr[i].s = (short)lrand48(); + SeqPtr[i].l = lrand48(); + SeqPtr[i].d = drand48(); + while (!isprint(c & 0x7f)) + c++; + SeqPtr[i].c = (c++ & 0x7f); + while (!isprint(c & 0x7f)) + c++; + SeqPtr[i].o = (unsigned char)(c++ & 0x7f); + } + Sseq = new ttcp_sequence::StructSeq(num, num, SeqPtr); + + } + break; + case SEND_OCTET: + default: + { + register CORBA::Octet *SeqPtr = (CORBA::Octet *)cp; + register char c = 0; + num = bufLen/sizeof(CORBA::Octet); + for(i=0; i < num; i++){ + while (!isprint(c & 0x7f)) + c++; + SeqPtr[i] = (c++ & 0x7f); + } + oseq = new ttcp_sequence::OctetSeq(num, num, SeqPtr); + } + break; + } +} + +// print all the statistics +void PrintStats (void) +{ + if (cput <= 0.0) + cput = 0.001; + if (realt <= 0.0) + realt = 0.001; + + if (title != 0) + { + double tmp; + FILE *outFile; + char filename[BUFSIZ]; + + strcpy(filename, title); + switch(dt){ + case SEND_SHORT: + strcat(filename, ".shortSeq.results"); + break; + case SEND_LONG: + strcat(filename, ".longSeq.results"); + break; + case SEND_DOUBLE: + strcat(filename, ".doubleSeq.results"); + break; + case SEND_CHAR: + strcat(filename, ".charSeq.results"); + break; + case SEND_STRUCT: + strcat(filename, ".structSeq.results"); + break; + case SEND_COMPOSITE: + strcat(filename, ".compositeSeq.results"); + break; + case SEND_OCTET: + default: + strcat(filename, ".octetSeq.results"); + break; + } + outFile = fopen (filename, "a+"); + ACE_OS::fprintf (outFile, "\n%ldk \t", buflen / 1024); + tmp = ((double) nbytes) / realt; + ACE_OS::fprintf (outFile, "%.2f ", tmp * 8.0 / 1024.0 / 1024.0); + fclose (outFile); + } + + ACE_OS::fprintf (stdout, + "ttcp%s: %ld bytes in %.2f real seconds = %s/sec +++\n", + trans ? "-t" : "-r", + nbytes, realt, outfmt (((double) nbytes) / realt)); + if (verbose) + { + ACE_OS::fprintf (stdout, + "ttcp%s: %ld bytes in %.2f CPU seconds = %s/cpu sec\n", + trans ? "-t" : "-r", + nbytes, cput, outfmt (((double) nbytes) / cput)); + } + ACE_OS::fprintf (stdout, + "ttcp%s: %d Server Method calls, msec/call = %.2f, calls/sec = %.2f\n", + trans ? "-t" : "-r", + numCalls, + 1024.0 * realt / ((double) numCalls), + ((double) numCalls) / realt); + ACE_OS::fprintf (stdout, "ttcp%s: %s\n", trans ? "-t" : "-r", stats); + if (verbose) + { + ACE_OS::fprintf (stdout, + "ttcp%s: buffer address %#x\n", + trans ? "-t" : "-r", + buf); + } +} |