diff options
Diffstat (limited to 'TAO/performance-tests/Cubit/COOL')
24 files changed, 3760 insertions, 0 deletions
diff --git a/TAO/performance-tests/Cubit/COOL/IDL_Cubit/Makefile b/TAO/performance-tests/Cubit/COOL/IDL_Cubit/Makefile new file mode 100644 index 00000000000..8a1b18e7113 --- /dev/null +++ b/TAO/performance-tests/Cubit/COOL/IDL_Cubit/Makefile @@ -0,0 +1,144 @@ +#---------------------------------------------------------------------------- +# $Id$ +# +# Makefile for the CHORUS COOL Cubit tests +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +IDL_SRC = cubit.cpp cubit.H sk_cubit.C sk_cubit.H + +SRC = $(IDL_SRC) cubit_i.cpp server.cpp client.cpp tmplinst.cpp + +SVR_OBJS = cubit_i.o server.o cubit.o tmplinst.o + +CLT_OBJS = client.o cubit.o tmplinst.o + +#---------------------------------------------------------------------------- +# 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 --binding Cubit Cubit_i --binding Cubit_Factory Cubit_Factory_i + +ifdef CHORUS + LDLIBS += -lOrb +else + LDLIBS += -lOrb-mt $(MATHLIB) +endif + +VLDLIBS := $(LDLIBS:%=%$(VAR)) $(ACELIB) $(LIBS) + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +all: $(IDL_SRC) server client + +$(IDL_SRC): cubit.idl + $(CHORUS_BINDIR)/chic $(IDLFLAGS) cubit.idl + -/bin/mv cubit.C cubit.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 cubit.cpp cubit.H sk_cubit.C sk_cubit.H server client + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/cubit.o .obj/cubit.so .shobj/cubit.o .shobj/cubit.so: cubit.cpp cubit.H +.obj/sk_cubit.o .obj/sk_cubit.so .shobj/sk_cubit.o .shobj/sk_cubit.so: sk_cubit.C +.obj/cubit_i.o .obj/cubit_i.so .shobj/cubit_i.o .shobj/cubit_i.so: cubit_i.cpp cubit_i.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/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 cubit.H sk_cubit.H +.obj/server.o .obj/server.so .shobj/server.o .shobj/server.so: server.cpp \ + $(ACE_ROOT)/ace/Get_Opt.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/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 \ + $(ACE_ROOT)/ace/Get_Opt.i cubit_i.h cubit.H \ + sk_cubit.H sk_cubit.C +.obj/client.o .obj/client.so .shobj/client.o .shobj/client.so: client.cpp \ + $(ACE_ROOT)/ace/Profile_Timer.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/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 \ + $(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 \ + $(ACE_ROOT)/ace/Env_Value_T.h \ + $(ACE_ROOT)/ace/Env_Value_T.i client.h \ + $(ACE_ROOT)/ace/Get_Opt.h \ + $(ACE_ROOT)/ace/Get_Opt.i cubit.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/api/api.H \ + sk_cubit.H +.obj/tmplinst.o .obj/tmplinst.so .shobj/tmplinst.o .shobj/tmplinst.so: tmplinst.cpp cubit.H \ + /project/doc/miniCOOL/minicool.r4.3/solaris2.5-CC-mt/include/corba/cool.H + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/TAO/performance-tests/Cubit/COOL/IDL_Cubit/README b/TAO/performance-tests/Cubit/COOL/IDL_Cubit/README new file mode 100644 index 00000000000..5987e0d6df2 --- /dev/null +++ b/TAO/performance-tests/Cubit/COOL/IDL_Cubit/README @@ -0,0 +1,34 @@ +This is the cubit example that uses the TAO IDL compiler to generate +the stubs and skeletons. Additional features include presence of a +factory to create Cubit objects and testing the _bind call to get the +factory object reference. + +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. + +server: +------- + +% server [-d] [-ORBhost <serverhost>] [-ORBport <portnum>] + [-n <number-of-cubit-objects>] + +The server cubit factory maintained num_of_cubit objects (default = +1). They are assigned keys that look like "key0", "key1", ... + +When the server is started and you have used the -d flag, you should +see as the first line of output something that looks like + iiop:1.0//serverhost:10013/factory (using -ORBobjrefstyle url) +or + IOR:000000000000001649444c3a43756269745... (using default -ORBobjrefstyle ior) + +Using -d turns on debugging messages. It is additive, i.e., the more +-d options provided, the more debugging you can get. At the moment, +only 2 levels of debugging are implemented, and more than 2 -d options +are ignored. + +client: +------- + +% client [-d] -h <hostname> -p <port> -k <cubit key> -n <iterations> + +cubit_key corresponds to "key0", "key1", ... diff --git a/TAO/performance-tests/Cubit/COOL/IDL_Cubit/client.cpp b/TAO/performance-tests/Cubit/COOL/IDL_Cubit/client.cpp new file mode 100644 index 00000000000..2fc718168c6 --- /dev/null +++ b/TAO/performance-tests/Cubit/COOL/IDL_Cubit/client.cpp @@ -0,0 +1,749 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// TAO/tests/IDL_Cubit +// +// = FILENAME +// clnt.cpp +// +// = DESCRIPTION +// This class implements a simple "cube" CORBA client for the Cubit +// example using stubs generated by the TAO ORB IDL compiler. +// +// = AUTHORS +// Copyright 1994-1995 by Sun Microsystems Inc. +// and +// Aniruddha Gokhale, Sumedh Mungee, and Sergio Flores-Gaitan +// +// ============================================================================ + +#include "ace/Profile_Timer.h" +#include "ace/Env_Value_T.h" +#include "client.h" + +#include "api/api.H" +#include "cubit.H" +#include "sk_cubit.H" + +ACE_RCSID(IDL_Cubit, client, "$Id$") + +// Constants +u_int _debug_level = 0; +const u_int DEFAULT_PORT = 3000; +CORBA::Environment Cubit_Client::env_; + + +// Constructor. + +#define quote(x) #x + +Cubit_Client::Cubit_Client (void) + : cubit_factory_key_ ("factory"), + cubit_key_ ("key0"), + hostname_ (ACE_DEFAULT_SERVER_HOST), + loop_count_ (250), + exit_later_ (0), + factory_ (Cubit_Factory::_nil ()), + objref_ (CORBA::Object::_nil ()), + cubit_ (Cubit::_nil ()), + orb_ptr_ (0), + call_count_ (0), + error_count_ (0), + portnum_(DEFAULT_PORT) +{ +} + +// Simple function that returns the substraction of 117 from the +// parameter. + +int +Cubit_Client::func (u_int i) +{ + return i - 117; +} + +// Parses the command line arguments and returns an error status. + +int +Cubit_Client::parse_args (void) +{ + ACE_Get_Opt get_opts (argc_, argv_, "dn:h:p:k:x"); + int c; + + while ((c = get_opts ()) != -1) + switch (c) + { + case 'd': // debug flag + _debug_level++; + break; + case 'n': // loop count + loop_count_ = (u_int) ACE_OS::atoi (get_opts.optarg); + break; + case 'h': + hostname_ = ACE_OS::strdup (get_opts.optarg); + break; + case 'p': + portnum_ = ACE_OS::atoi (get_opts.optarg); + break; + case 'k': // stringified objref + cubit_key_ = ACE_OS::strdup (get_opts.optarg); + break; + case 'x': + this->exit_later_++; + break; + case '?': + default: + ACE_ERROR_RETURN ((LM_ERROR, + "usage: %s" + " [-d]" + " [-n loopcount]" + " [-k cubit-obj-ref-key]" + " [-h hostname]" + " [-p port]" + " [-x]" + "\n", + this->argv_ [0]), + -1); + } + + // Indicates successful parsing of command line. + return 0; +} + +// Exercise the union. Cube a union. + +void +Cubit_Client::cube_union_stub (void) +{ + CORBA::Environment env; + Cubit::oneof u, r; + + this->call_count_++; + + u.l (3); // use the long union branch + + // Cube a "union" ... + r = this->cubit_->cube_union (u, this->env_); + + if (this->env_.exception () != 0) + { + this->print_exception ("from cube_union"); + this->error_count_++; + } + else + { + if (_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, "cube union ...")); + u.l (u.l () * u.l () * u.l ()) ; + + if (u.l () != r.l ()) + { + ACE_DEBUG ((LM_DEBUG, "** cube_union ERROR\n")); + this->error_count_++; + } + + } + + this->call_count_++; + + u._d (Cubit::e_3rd); +#if 0 + u.cm ().l = this->func (i); + u.cm ().s = this->func (i); + u.cm ().o = this->func (i); +#endif + + u.cm ().l = 7; + u.cm ().s = 5; + u.cm ().o = 3; + + // Cube another "union" which uses the default arm ... NOT tested yet + r = this->cubit_->cube_union (u, this->env_); + + if (this->env_.exception () != 0) + { + this->print_exception ("from cube_union"); + this->error_count_++; + } + else + { + if (_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, "cube union ...")); + u.cm ().l = u.cm ().l * u.cm ().l * u.cm ().l; + u.cm ().s = u.cm ().s * u.cm ().s * u.cm ().s; + u.cm ().o = u.cm ().o * u.cm ().o * u.cm ().o; + + if (u.cm ().l != r.cm ().l + || u.cm ().s != r.cm ().s + || u.cm ().o != r.cm ().o) + { + ACE_DEBUG ((LM_DEBUG, "** cube_union ERROR\n")); + this->error_count_++; + } + } +} + +// Exercise the union using dii. + +void +Cubit_Client::cube_union_dii (void) +{ + // Create the request ... + CORBA::Request_ptr req; + + this->call_count_++; + + req = this->cubit_->_request ((CORBA::String) "cube_union", this->env_); + + if (this->env_.exception () != 0) + { + this->error_count_++; + + this->print_exception ("cube_union_dii request create"); + return; + } + + // ... initialise the argument list and result ... + Cubit::oneof *u, r; + + u = new Cubit::oneof; + u->_d (Cubit::e_3rd); + + u->cm ().l = 5; + u->cm ().s = -7; + u->cm ().o = 3; + + CORBA::Any tmp_arg (Cubit::_tc_oneof, u, CORBA_FALSE); + + req->arguments ()->add_value ("values", tmp_arg, CORBA_ARG_IN, this->env_); + + if (this->env_.exception () != 0) + { + this->error_count_++; + this->print_exception ("cube_union_dii request arg add"); + CORBA::release (req); + return; + } + + req->result ()->value ()->replace (Cubit::_tc_oneof, 0, CORBA_TRUE); + + if (this->env_.exception () != 0) + { + this->error_count_++; + this->print_exception ("cube_union_dii result type"); + CORBA::release (req); + return; + } + + // Make the invocation, verify the result. + + req->invoke (); + + if (req->env ()->exception () != 0) + { + this->error_count_++; + this->print_exception ("cube_union_dii invoke", *req->env ()); + CORBA::release (req); + return; + } + + r = *(Cubit::oneof *) req->result ()->value ()->value (); + + if (r.cm ().o != 27 || r.cm ().l != 125 || r.cm ().s != -343) + { + this->error_count_++; + ACE_ERROR ((LM_ERROR, "cube_union_dii -- bad results\n")); + } + else + ACE_DEBUG ((LM_DEBUG, "cube_union_dii ... success!!")); + + CORBA::release (req); + delete u; +} + +// Cube a short. + +void +Cubit_Client::cube_short (int i) +{ + CORBA::Short arg_short = this->func (i); + // Cube a short. + CORBA::Short ret_short = cubit_->cube_short (arg_short, this->env_); + + this->call_count_++; + + if (this->env_.exception () != 0) + { + this->print_exception ("from cube_short"); + this->error_count_++; + } + else + { + if (_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, "cube short: %d --> %d\n", + arg_short, + ret_short)); + arg_short = arg_short * arg_short * arg_short; + + if (arg_short != ret_short) + { + ACE_ERROR ((LM_ERROR, "** cube_short (%d) ERROR (--> %d)\n", + (CORBA::Short) this->func (i), + ret_short)); + this->error_count_++; + } + } +} + +// Cube an octet + +void +Cubit_Client::cube_octet (int i) +{ + CORBA::Octet arg_octet = this->func (i); + + // Cube an octet. + CORBA::Octet ret_octet = this->cubit_->cube_octet (arg_octet, this->env_); + + this->call_count_++; + + if (this->env_.exception () != 0) + { + this->print_exception ("from cube_octet"); + this->error_count_++; + } + else + { + if (_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, "cube octet: %d --> %d\n", arg_octet, ret_octet)); + arg_octet = arg_octet * arg_octet * arg_octet; + if (arg_octet != ret_octet) { + ACE_DEBUG ((LM_DEBUG, + "** cube_octet (%d) ERROR (--> %d)\n", + (CORBA::Octet) this->func (i), + ret_octet)); + this->error_count_++; + } + } +} + +// calculate the cube from a long + +void +Cubit_Client::cube_long (int i) +{ + CORBA::Long arg_long = this->func (i); + + // Cube a long. + CORBA::Long ret_long = this->cubit_->cube_long (arg_long, this->env_);; + + this->call_count_++; + + if (this->env_.exception () != 0) + { + this->print_exception ("from cube_long"); + this->error_count_++; + } + else + { + if (_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, "cube long: %d --> %d\n", arg_long, ret_long)); + arg_long = arg_long * arg_long * arg_long; + if (arg_long != ret_long) { + ACE_ERROR ((LM_ERROR, + "** cube_long (%ld) ERROR (--> %ld)\n", + (CORBA::Long) this->func (i), + ret_long)); + this->error_count_++; + } + } +} + +// Cube the numbers in a struct + +void +Cubit_Client::cube_struct (int i) +{ + Cubit::Many arg_struct; + Cubit::Many ret_struct; + + this->call_count_++; + + arg_struct.l = this->func (i); + arg_struct.s = this->func (i); + arg_struct.o = this->func (i); + + // Cube a "struct" ... + ret_struct = this->cubit_->cube_struct (arg_struct, this->env_); + + if (this->env_.exception () != 0) + { + this->print_exception ("from cube_struct"); + this->error_count_++; + } + else + { + if (_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, "cube struct ...")); + arg_struct.l = arg_struct.l * arg_struct.l * arg_struct.l; + arg_struct.s = arg_struct.s * arg_struct.s * arg_struct.s; + arg_struct.o = arg_struct.o * arg_struct.o * arg_struct.o; + + if (arg_struct.l != ret_struct.l + || arg_struct.s != ret_struct.s + || arg_struct.o != ret_struct.o) + { + ACE_ERROR ((LM_ERROR, "** cube_struct ERROR\n")); + this->error_count_++; + } + } +} + +// Cube the numbers in a struct + +void +Cubit_Client::cube_struct_dii (void) +{ + // Create the request ... + CORBA::Request_ptr req = + this->cubit_->_request ((CORBA::String) "cube_struct", this->env_); + + this->call_count_++; + + if (this->env_.exception () != 0) + { + this->print_exception ("DII request create"); + return; + } + + // ... initialise the argument list and result ... + Cubit::Many arg; + Cubit::Many result; + + arg.o = 3; + arg.l = 5; + arg.s = -7; + + CORBA::Any tmp_arg (Cubit::_tc_Many, &arg, CORBA_FALSE); + + req->arguments ()->add_value ("values", tmp_arg, CORBA_ARG_IN, this->env_); + + if (this->env_.exception () != 0) + { + this->print_exception ("DII request arg add"); + CORBA::release (req); + return; + } + + req->result ()->value ()->replace (Cubit::_tc_Many, 0, CORBA_TRUE); + + if (this->env_.exception () != 0) + { + this->print_exception ("DII request result type"); + CORBA::release (req); + return; + } + + // Make the invocation, verify the result + + req->invoke (); + + if (req->env ()->exception () != 0) + { + this->print_exception ("DII invoke sending struct", *req->env ()); + CORBA::release (req); + return; + } + + result = *(Cubit::Many *) req->result ()->value ()->value (); + + if (result.o != 27 || result.l != 125 || result.s != -343) + ACE_ERROR ((LM_ERROR, "DII cube_struct -- bad results\n")); + else + ACE_DEBUG ((LM_DEBUG, "DII cube_struct ... success!!")); + + CORBA::release (req); +} + +void +Cubit_Client::print_stats (const char *call_name, ACE_Profile_Timer::ACE_Elapsed_Time &elapsed_time) +{ + double tmp; + + ACE_DEBUG ((LM_DEBUG, + "%s:\n", + call_name)); + + if (this->call_count_ > 0 && this->error_count_ == 0) + { + tmp = 1000 / elapsed_time.real_time; + + elapsed_time.real_time *= ACE_ONE_SECOND_IN_MSECS; + elapsed_time.user_time *= ACE_ONE_SECOND_IN_MSECS; + elapsed_time.system_time *= ACE_ONE_SECOND_IN_MSECS; + + elapsed_time.real_time /= this->call_count_; + elapsed_time.user_time /= this->call_count_; + elapsed_time.system_time /= this->call_count_; + + tmp = 1000 / elapsed_time.real_time; + + ACE_DEBUG ((LM_DEBUG, + "\treal_time\t= %0.06f ms, \n\t" + "user_time\t= %0.06f ms, \n\t" + "system_time\t= %0.06f ms\n" + "\t%0.00f calls/second\n", + elapsed_time.real_time < 0.0? 0.0:elapsed_time.real_time, + elapsed_time.user_time < 0.0? 0.0:elapsed_time.user_time, + elapsed_time.system_time < 0.0? 0.0:elapsed_time.system_time, + tmp < 0.0? 0.0 : tmp)); + } + else + { + ACE_ERROR ((LM_ERROR, "\tNo time stats printed. Call count zero or error ocurred.\n")); + } + + ACE_DEBUG ((LM_DEBUG, + "\t%d calls, %d errors\n", + this->call_count_, + this->error_count_)); +} + +// Execute client example code. + +int +Cubit_Client::run (void) +{ + u_int i; + + ACE_Profile_Timer timer; + ACE_Profile_Timer::ACE_Elapsed_Time elapsed_time; + + // ACE_Time_Value before; + + // We start an ACE_Profile_Timer here... + timer.start (); + + // Make the calls in a loop. + for (i = 0; i < this->loop_count_; i++) + { + this->cube_short (i); + this->cube_octet (i); + this->cube_long (i); + this->cube_struct (i); + } + + // stop the timer. + timer.stop (); + + timer.elapsed_time (elapsed_time); + // compute call average call time. + this->print_stats ("cube average call", elapsed_time); + + +#if 0 // this test is segfaulting, comment for now. + // Simple test for DII: call "cube_struct". (It's not timed since + // the copious mallocation of DII would bias numbers against typical + // stub-based calls). + + timer.start (); + + this->call_count_ = 0; + this->error_count_ = 0; + // Make the calls in a loop. + for (i = 0; i < this->loop_count_; i++) + { + this->cube_struct_dii (); + } + timer.stop (); + + timer.elapsed_time (elapsed_time); + // compute call average call time. + this->print_stats ("cube_struct_dii call", elapsed_time); + + // ------------------> + // Two more tests, using the "cube_union" function + + // unions using stubs + timer.start (); + + this->call_count_ = 0; + this->error_count_ = 0; + // Make the calls in a loop. + for (i = 0; i < this->loop_count_; i++) + { + this->cube_union_stub (); + } + + timer.stop (); + + timer.elapsed_time (elapsed_time); + // compute call average call time. + this->print_stats ("cube_union_stub call", elapsed_time); + + // union DII + timer.start (); + + this->call_count_ = 0; + this->error_count_ = 0; + // Make the calls in a loop. + for (i = 0; i < this->loop_count_; i++) + { + this->cube_union_dii (); + } + + timer.stop (); + + timer.elapsed_time (elapsed_time); + // compute call average call time. + this->print_stats ("cube_union_dii call", elapsed_time); +#endif + if (this->exit_later_) + { + this->cubit_->please_exit (this->env_); + this->print_exception ("server, please ACE_OS::exit", this->env_); + } + + return this->error_count_ == 0 ? 0 : 1; +} + +Cubit_Client::~Cubit_Client (void) +{ + // Free resources + CORBA::release (this->factory_); + CORBA::release (this->cubit_); +} + +int +Cubit_Client::init (int argc, char **argv) +{ + this->argc_ = argc; + this->argv_ = argv; + + // Retrieve the ORB. + this->orb_ptr_ = CORBA::ORB_init (this->argc_, + this->argv_, + 0, + this->env_); + + // Parse command line and verify parameters. + if (this->parse_args () == -1) + return -1; + + if (this->env_.exception () != 0) + { + this->print_exception ("ORB initialization"); + return -1; + } + + if (this->cubit_key_ == 0) + ACE_ERROR_RETURN ((LM_ERROR, + "%s: must specify an object reference using -k <key>\n", + this->argv_[0]), + -1); + + // Retrieve a factory objref. + char ior[BUFSIZ]; + sprintf ( ior, "cool-tcp://%s:%d", this->hostname_, this->portnum_ ); + + ACE_DEBUG ((LM_DEBUG, "ior is \"%s\"\n", ior)); + + COOL::EOABindingData bindingData (ior); + + this->factory_ = Cubit_Factory::_bind(bindingData, this->env_); + + // this->objref_ = Cubit_Factory::_bind (this->hostname_, + // this->portnum_, + // this->cubit_factory_key_, + // this->env_); + + if (this->env_.exception () != 0) + { + this->print_exception ("Cubit_Factory::_bind"); + return -1; + } + + if (CORBA::is_nil (this->factory_) == CORBA_TRUE) + ACE_ERROR_RETURN ((LM_ERROR, + " _bind returned null object for host (%s), port (%d)\n", + this->hostname_, + this->portnum_), + -1); + + // Narrow the CORBA::Object reference to the stub object, checking + // the type along the way using _is_a. There is really no need to + // narrow <objref> because <_bind> will return us the + // <Cubit_Factory> pointer. However, we do it so that we can + // explicitly test the _narrow function. + +//this->factory_ = Cubit_Factory::_narrow (this->objref_, this->env_); + + //CORBA::release (this->objref_); + // this->objref_->Release (); + + // if (this->factory_ == 0) + // ACE_ERROR_RETURN ((LM_ERROR, + // " (%P|%t) Unable to narrow object reference to a Cubit_Factory_ptr.\n"), + // -1); + + // Now retrieve the Cubit obj ref corresponding to the key. + this->cubit_ = + this->factory_->make_cubit (this->cubit_key_, this->env_); + + if (this->env_.exception () != 0) + { + this->print_exception ("make_cubit"); + return -1; + } + + if (CORBA::is_nil (this->cubit_)) + ACE_ERROR_RETURN ((LM_ERROR, + "null cubit objref returned by factory\n"), + -1); + + return 0; +} + +void Cubit_Client::print_exception (const char * str, + const CORBA_Environment &env) +{ + CORBA::SystemException* ex; + + ex = CORBA::SystemException::_narrow(env.exception()); + + if (ex) + { + CORBA::String_var msg = ex->message(); + fprintf(stderr, "%s: %s.\n", str, (const char *) msg); + } + else + { + fprintf(stderr, "%s: Unknown user exception.\n", str); + } +} + + + + +// This function runs the test. + +int +main (int argc, char **argv) +{ + Cubit_Client cubit_client; + + if (cubit_client.init (argc, argv) == -1) + return 1; + else + return cubit_client.run (); +} + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) +template class ACE_Env_Value<unsigned long>; +template class ACE_Env_Value<unsigned short>; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +#pragma instantiate ACE_Env_Value<unsigned long> +#pragma instantiate ACE_Env_Value<unsigned short> +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/performance-tests/Cubit/COOL/IDL_Cubit/client.h b/TAO/performance-tests/Cubit/COOL/IDL_Cubit/client.h new file mode 100644 index 00000000000..94cc36a14bd --- /dev/null +++ b/TAO/performance-tests/Cubit/COOL/IDL_Cubit/client.h @@ -0,0 +1,128 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// TAO/tests/IDL_Cubit +// +// = FILENAME +// clnt.h +// +// = DESCRIPTION +// This class implements a simple "cube" CORBA client for the Cubit +// example using stubs generated by the TAO ORB IDL compiler. +// +// = AUTHORS +// Copyright 1994-1995 by Sun Microsystems Inc. +// and +// Aniruddha Gokhale, Sumedh Mungee, and Sergio Flores-Gaitan +// +// ============================================================================ + +#include "ace/Get_Opt.h" +#include "cubit.H" + +class Cubit_Client + // = TITLE + // Defines a class that encapsulates behaviour of the Cubit client + // example. Provides a better understanding of the logic in an + // object oriented way. + // + // = DESCRIPTION + // This class declares an interface to run the example client for + // Cubit CORBA server. All the complexity for initializing the + // server is hidden in the class. Just the run() interface is needed. +{ +public: + // = Constructor and destructor. + Cubit_Client (void); + ~Cubit_Client (void); + + int run (void); + // Execute client example code. + + int init (int argc, char **argv); + // Initialize the client communication endpoint with server. + + void print_exception (const char * str, + const CORBA_Environment &env=Cubit_Client::env_); + +private: + int func (u_int i); + // simple function that returns the substraction of 117 from the parameter. + + int parse_args (void); + // Parses the arguments passed on the command line. + + void print_stats (const char *call_name, ACE_Profile_Timer::ACE_Elapsed_Time &elapsed_time); + // prints the time stats + + void cube_union_stub (void); + // Exercise the union. Cube a union. + + void cube_union_dii (void); + // Exercise the union using dii. + + void cube_struct (int i); + // calculate the cube from a struct. + + void cube_long (int i); + // calculate the cube from a long + + void cube_octet (int i); + // Cube an octet + + void cube_short (int i); + // Cube a short. + + void cube_sequence (int i); + // Cube a sequence. + + void cube_struct_dii (void); + // Cube the numbers in a struct + + int argc_; + // # of arguments on the command line. + + char **argv_; + // arguments from command line. + + const char *cubit_factory_key_; + // Key of factory obj ref. + + char *cubit_key_; + // Key of the obj ref to be retrieved via the factory. + + char *hostname_; + // Hostname of server. + + CORBA::UShort portnum_; + // default port number of server. + + u_int loop_count_; + // Number of times to do the cube operations. + + int exit_later_; + // Flag to tell server to not exit immediately + + Cubit_Factory_ptr factory_; + // factory pointer for cubit. + + CORBA::Object_ptr objref_; + // storage of the factory objref + + static CORBA::Environment env_; + // Environment variable + + Cubit_ptr cubit_; + // Cubit obj ref + + CORBA::ORB_ptr orb_ptr_; + // Remember our orb + + u_int call_count_; + // # of calls made to functions + + u_int error_count_; + // # of errors incurred in the lifetime of the application. +}; diff --git a/TAO/performance-tests/Cubit/COOL/IDL_Cubit/cubit.idl b/TAO/performance-tests/Cubit/COOL/IDL_Cubit/cubit.idl new file mode 100644 index 00000000000..9ddc2d8954f --- /dev/null +++ b/TAO/performance-tests/Cubit/COOL/IDL_Cubit/cubit.idl @@ -0,0 +1,71 @@ +// $Id$ + +interface Cubit + // = TITLE + // Defines an interface that encapsulates operations that cube + // numbers. + // + // = DESCRIPTION + // This interface encapsulates operations that cube + // octets, shorts, longs, structs and unions. + +{ + octet cube_octet (in octet o); + // cube an octet + + short cube_short (in short s); + // cube a short + + long cube_long (in long l); + // cube a long + + struct Many + { + octet o; // + 3 bytes padding (normally) ... + long l; + short s; // + 2 bytes padding (normally) ... + }; + + Many cube_struct (in Many values); + // Cube a struct + + enum discrim + { + e_0th, + e_1st, + e_2nd, + e_3rd + }; + // Enumeration of the different elements in a union. + + union oneof switch (discrim) + { + // this is an easy union to interpret; no padding + // is needed between discriminant and value. + case e_0th: + octet o; + case e_1st: + short s; + case e_2nd: + long l; + case e_3rd: + Many cm; + + // default: + // Many cm; + }; + // Union of different types. + + oneof cube_union (in oneof values); + // cube a union. + + oneway void please_exit (); + // shutdown the application. +}; + +interface Cubit_Factory + // = TITLE + // Creates Cubit objects +{ + Cubit make_cubit (in string key); +}; diff --git a/TAO/performance-tests/Cubit/COOL/IDL_Cubit/cubit_i.cpp b/TAO/performance-tests/Cubit/COOL/IDL_Cubit/cubit_i.cpp new file mode 100644 index 00000000000..74ef088ee8e --- /dev/null +++ b/TAO/performance-tests/Cubit/COOL/IDL_Cubit/cubit_i.cpp @@ -0,0 +1,191 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// TAO/tests/IDL_Cubit +// +// = FILENAME +// cubit_i.cpp +// +// = AUTHOR +// Andy Gokhale, Sumedh Mungee and Sergio Flores-Gaitan +// +// ============================================================================ + +#include "cubit_i.h" +#include <api/api.H> +#include <api/binding.H> +#include <corba/eoa.H> +#include <corba/eorb.H> + +ACE_RCSID(IDL_Cubit, cubit_i, "$Id$") + +extern void print_exception (const CORBA_Environment &env, const char * str); + +// Constructor + +Cubit_Factory_i::Cubit_Factory_i (const char *key, int numobjs) +{ + // Create implementation object with user specified key. + + this->numobjs_ = numobjs; + this->my_cubit_ = new Cubit_i_ptr [this->numobjs_]; + + static char obj_str [MAXNAMELEN]; + + for (u_int i = 0; i < this->numobjs_; i++) + { + ACE_OS::memset (obj_str, '\0', MAXNAMELEN); + ACE_OS::sprintf (obj_str, "key%d", i); + + my_cubit_[i] = new Cubit_i (obj_str); + + if (my_cubit_[i] == 0) + ACE_ERROR ((LM_ERROR, + " (%P|%t) Unable to create implementation object%d\n", + i)); + + } +} + +// Destructor + +Cubit_Factory_i::~Cubit_Factory_i (void) +{ + delete [] this->my_cubit_; +} + +Cubit_ptr +Cubit_Factory_i::make_cubit (const char *key, CORBA::Environment &env) +{ + Cubit_ptr cb = 0; + + for (size_t i = 0; i < this->numobjs_; i++) + { + const char *obj_str = this->my_cubit_[i]->_get_name (); + + // Keys matched. + if (!ACE_OS::strcmp (obj_str, key)) + { + COOL_bind(*(this->my_cubit_ [i]), cb, env); + if (env.exception() != 0) + print_exception (env, "COOL_bind"); + // return Cubit::_duplicate (this->my_cubit_ [i]); + return cb; + } + } + + return Cubit::_nil (); +} + +// Constructor + +Cubit_i::Cubit_i (const char *obj_name) + // : POA_Cubit (obj_name) +{ + obj_name_ = ACE_OS::strdup (obj_name); +} + +const char * +Cubit_i::_get_name (void) +{ + return this->obj_name_; +} + +// Destructor + +Cubit_i::~Cubit_i (void) +{ +} + +// Cube an octet + +CORBA::Octet +Cubit_i::cube_octet (CORBA::Octet o, + CORBA::Environment &env) +{ + ACE_UNUSED_ARG (env); + return o * o * o; +} + +// Cube a short. + +CORBA::Short +Cubit_i::cube_short (CORBA::Short s, + CORBA::Environment &env) +{ + ACE_UNUSED_ARG (env); + return s * s * s; +} + +// Cube a long + +CORBA::Long +Cubit_i::cube_long (CORBA::Long l, + CORBA::Environment &env) +{ + ACE_UNUSED_ARG (env); + return l * l * l; +} + +// Cube a struct + +Cubit::Many +Cubit_i::cube_struct (const Cubit::Many &values, + CORBA::Environment &env) +{ + Cubit::Many temp; + + ACE_UNUSED_ARG (env); + temp.o = values.o * values.o * values.o; + temp.s = values.s * values.s * values.s; + temp.l = values.l * values.l * values.l; + + return temp; +} + +// Cube a union + +Cubit::oneof +Cubit_i::cube_union (const Cubit::oneof &values, + CORBA::Environment &env) +{ + Cubit::oneof temp; + + ACE_UNUSED_ARG (env); + switch (values._d ()) + { + case Cubit::e_0th: + temp.o (values.o () * values.o () * values.o ()); + break; + case Cubit::e_1st: + temp.s (values.s () * values.s () * values.s ()); + break; + case Cubit::e_2nd: + temp.l (values.l () * values.l () * values.l ()); + break; + case Cubit::e_3rd: + default: + temp._d (values._d ()); // set the discriminant + // use the read/write accessor + temp.cm ().o = values.cm ().o * values.cm ().o * values.cm ().o; + temp.cm ().s = values.cm ().s * values.cm ().s * values.cm ().s; + temp.cm ().l = values.cm ().l * values.cm ().l * values.cm ().l; + + } + return temp; +} + +// Shutdown. + +void Cubit_i::please_exit (CORBA::Environment &env) +{ + // Macro to avoid "warning: unused parameter" type warning. + ACE_UNUSED_ARG (env); + + ACE_DEBUG ((LM_DEBUG, "I've been asked to shut down...")); + thisCapsule->boa()->shutdown(); + + CORBA_BOA::deactivate_object(this, env); +} diff --git a/TAO/performance-tests/Cubit/COOL/IDL_Cubit/cubit_i.h b/TAO/performance-tests/Cubit/COOL/IDL_Cubit/cubit_i.h new file mode 100644 index 00000000000..9db23e7dbb6 --- /dev/null +++ b/TAO/performance-tests/Cubit/COOL/IDL_Cubit/cubit_i.h @@ -0,0 +1,109 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// TAO/tests/IDL_Cubit +// +// = FILENAME +// cubit_i.h +// +// = AUTHOR +// Andy Gokhale, Sumedh Mungee and Sergio Flores-Gaitan +// +// ============================================================================ + +#if !defined (_CUBIT_I_HH) +#define _CUBIT_I_HH + +#include "ace/ACE.h" + +#include <api/api.H> +#include <api/binding.H> +#include <corba/eoa.H> +#include <corba/eorb.H> + +extern COOL_CurrentCapsule* thisCapsule; + +#include "cubit.H" +#include "sk_cubit.H" + +// Forward declarations +class Cubit_i; + +// Typedefs. +typedef Cubit_i *Cubit_i_ptr; +typedef Cubit_i_ptr Cubit_i_ref; + +class Cubit_i + // = TITLE + // Illustrates how to integrate a servant with the + // generated skeleton. + // = DESCRIPTION + // Implementation of the cubit example at the servant side. + // Cubes an octet, short, long, struct and union. +{ +public: + Cubit_i (const char *obj_name = 0); + // Constructor + + ~Cubit_i (void); + // Destructor + + virtual CORBA::Octet cube_octet (CORBA::Octet o, + CORBA::Environment &env); + // Cube an octet + + virtual CORBA::Short cube_short (CORBA::Short s, + CORBA::Environment &env); + // Cube a short + + virtual CORBA::Long cube_long (CORBA::Long l, + CORBA::Environment &env); + // Cube a long + + virtual Cubit::Many cube_struct (const Cubit::Many &values, + CORBA::Environment &env); + // Cube a struct. + + virtual Cubit::oneof cube_union (const Cubit::oneof &values, + CORBA::Environment &env); + // Cube a union. + + virtual void please_exit (CORBA::Environment &env); + // Shutdown routine. + + const char *_get_name (void); + + private: + const char * obj_name_; +}; + + +class Cubit_Factory_i; + +typedef Cubit_Factory_i *Cubit_Factory_i_ptr; + +class Cubit_Factory_i + // =TITLE + // Cubit_Factory_i + // + // DESCRIPTION + // factory object returning the cubit objrefs +{ +public: + Cubit_Factory_i (const char *key, int numobjs); + // constructor + + ~Cubit_Factory_i (void); + // destructor + + virtual Cubit_ptr make_cubit (const char *key, CORBA::Environment &env); + // make the cubit object whose key is "key" + +private: + Cubit_i_ptr *my_cubit_; + u_int numobjs_; +}; + +#endif /* _CUBIT_I_HH */ diff --git a/TAO/performance-tests/Cubit/COOL/IDL_Cubit/server.cpp b/TAO/performance-tests/Cubit/COOL/IDL_Cubit/server.cpp new file mode 100644 index 00000000000..242810c72a5 --- /dev/null +++ b/TAO/performance-tests/Cubit/COOL/IDL_Cubit/server.cpp @@ -0,0 +1,151 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// TAO/tests/IDL_Cubit +// +// = FILENAME +// svr.cpp +// +// = AUTHOR +// Andy Gokhale, Sumedh Mungee and Sergio Flores-Gaitan +// +// ============================================================================ + +#include "ace/Get_Opt.h" +#include "ace/Log_Msg.h" + +#include "cubit_i.h" + +#include <api/binding.H> +#include <api/api.H> +#include "cubit.H" +#include "sk_cubit.H" +#include "sk_cubit.C" + +ACE_RCSID(IDL_Cubit, server, "$Id$") + +void print_exception (const CORBA_Environment &env, + const char * str) +{ + CORBA::SystemException* ex; + + ex = CORBA::SystemException::_narrow(env.exception()); + + if (ex) + { + CORBA::String_var msg = ex->message(); + fprintf(stderr, "%s: %s.\n", str, (const char *) msg); + } + else + { + fprintf(stderr, "Unknown user exception.\n"); + } +} + + +// Global Variables +static int num_of_objs = 1; + +u_int _debug_level = 0; + +// Parses the command line arguments and returns an error status + +static int +parse_args (int argc, char *argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, "dn:"); + int c; + + while ((c = get_opts ()) != -1) + switch (c) + { + case 'd': // debug flag + _debug_level++; + break; + case 'n': // number of cubit objects we hold + num_of_objs = ACE_OS::atoi (get_opts.optarg); + break; + case '?': + default: + ACE_ERROR_RETURN ((LM_ERROR, + "usage: %s" + " [-d]" + " [-n] <num of cubit objects>" + "\n", argv [0]), 1); + } + + return 0; // Indicates successful parsing of command line +} + +// Standard command line parsing utilities used. + +int +main (int argc, char *argv[]) +{ + CORBA::Environment env; + + COOL::EOA::bind(argv[1], env); + if (env.exception()) { + ACE_DEBUG ((LM_ERROR, "Impossible to bind the ORB to the description:%s\n", argv[1])); + return -1; + } + + CORBA::ORB_ptr orb_ptr = CORBA::ORB_init (argc, argv, 0, env); + + if (env.exception () != 0) + { + print_exception (env, "ORB init"); + return 1; + } + + // Initialize the Object Adapter + CORBA_BOA_ptr oa_ptr = orb_ptr->OA_init (argc, argv, 0, env); + + if (env.exception() != 0) + ACE_ERROR_RETURN ((LM_ERROR, + " (%P|%t) Unable to initialize the POA.\n"), + 1); + + // Parse remaining command line and verify parameters. + parse_args (argc, argv); + + // create a factory implementation + Cubit_Factory_ptr factory; + Cubit_Factory_i *factory_i; + COOL::EOABindingData bindingData; + + ACE_NEW_RETURN (factory_i, Cubit_Factory_i ("factory", num_of_objs), 1); + + COOL_bind (*factory_i, factory, bindingData, env); + + if (_debug_level > 0) + { + // Stringify the objref we'll be implementing, and print it to + // stdout. Someone will take that string and give it to a + // client. Then release the object. + + CORBA::String str; + + str = orb_ptr->object_to_string (factory, env); + + if (env.exception () != 0) + { + print_exception (env, "object_to_string"); + return -1; + } + + ACE_OS::puts ((char *) str); + ACE_OS::fflush (stdout); + + ACE_DEBUG ((LM_DEBUG, "listening as object '%s'\n", str)); + } + + // 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/Cubit/COOL/IDL_Cubit/tmplinst.cpp b/TAO/performance-tests/Cubit/COOL/IDL_Cubit/tmplinst.cpp new file mode 100644 index 00000000000..0a3fd6572db --- /dev/null +++ b/TAO/performance-tests/Cubit/COOL/IDL_Cubit/tmplinst.cpp @@ -0,0 +1,17 @@ +// +// $Id$ +// + +// The contents of this file REALLY should be generated by the IDL +// compiler, but that functionality isn't available yet. + +#include "cubit.H" + +ACE_RCSID(IDL_Cubit, tmplinst, "$Id$") + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) +template class TAO_Unbounded_Sequence<long>; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +#pragma instantiate TAO_Unbounded_Sequence<long> +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ + diff --git a/TAO/performance-tests/Cubit/COOL/MT_Cubit/Makefile b/TAO/performance-tests/Cubit/COOL/MT_Cubit/Makefile new file mode 100644 index 00000000000..d605120ca98 --- /dev/null +++ b/TAO/performance-tests/Cubit/COOL/MT_Cubit/Makefile @@ -0,0 +1,91 @@ +#---------------------------------------------------------------------------- +# $Id$ +# +# Makefile for the CHORUS COOL Cubit tests +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +IDL_SRC = cubit.cpp cubit.H sk_cubit.C sk_cubit.H + +SRC = $(IDL_SRC) \ + cubit_impl.cpp \ + server.cpp \ + client.cpp \ + Task_Client.cpp \ + Util_Thread.cpp + +SVR_OBJS = cubit_impl.o \ + server.o \ + cubit.o + +CLT_OBJS = Task_Client.o \ + client.o \ + cubit.o \ + Util_Thread.o + +#---------------------------------------------------------------------------- +# 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 Cubit Cubit_Impl + +# pccTimer will eventually get integrated into ACE. It is specific for +# ClassiX on VME +ifdef CHORUS + SRC += pccTimer.cpp + CLT_OBJS += pccTimer.o + LDLIBS += -lOrb +else + LDLIBS += -lOrb-mt +endif + +VLDLIBS := $(LDLIBS:%=%$(VAR)) $(ACELIB) $(LIBS) + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +all: $(IDL_SRC) server client + +$(IDL_SRC): cubit.idl + $(CHORUS_BINDIR)/chic $(IDLFLAGS) cubit.idl + -/bin/mv cubit.C cubit.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 cubit.cpp cubit.H sk_cubit.C sk_cubit.H server client + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/TAO/performance-tests/Cubit/COOL/MT_Cubit/README b/TAO/performance-tests/Cubit/COOL/MT_Cubit/README new file mode 100644 index 00000000000..f8e7941cbdf --- /dev/null +++ b/TAO/performance-tests/Cubit/COOL/MT_Cubit/README @@ -0,0 +1,166 @@ +The MT-Cubit example for the CHORUS COOL ORB +-------------------------------------------- + +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. + +server: +------- + +./server <tpr | tpool> + <cool-tcp://THIS_HOSTNAME:THIS_HOST_PORT | cool-chorus://:THIS_HOST_PORT> + -v + <-cool-tcp -cool-iiop | -cool-chorus> + +tpr : this indicates to the server to use the Thread Per Request concurrency model. + +tpool : this indicates to the server to use the Thread Pool concurrency model. + +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). + +The server will print the IOR of the high and low priority servants, +but it is not required by the client. + +client: +------- + +./client [-n <LOOP_COUNT>] + [-t <NUM_THREADS>] + [-h SERVER_HOSTNAME] + [-p <SERVER_PORT_NUM>] + [-cool-tcp -cool-iiop | -cool-chorus] + [-I] + +[-I] indicates to the client to use Chorus IPC as the underlying transport + instead of TCP + +<SERVER_HOSTNAME>: is the hostname of the server. + +<SERVER_PORT_NUM>: is the port number of the servant. + +Based on the SERVER_HOSTNAME and the SERVER_PORT_NUM, the client constructs +the IOR's for the high priority servant and the low priority servant. + +<LOOP_COUNT> : is the number of times the group of CORBA twoway calls are to + be made. The group consists of the following calls: cube_octet(), cube_short(), + cube_long() and cube_struct(). The default is 100 loops (i.e. 400 calls are made). + +<NUM_THREADS> : is the total number of concurrent clients to be + created. One of these clients will be a high priority client (and thus + send requests to the high priority servant), and the rest will have + low priority. + +The high priority client makes requests at 20Hz, and the low priority +clients make requests at 10Hz. + +Results +------- + +The client prints the latency observed by the high priority client, +and the average latency observed by the low priority client. + +Examples +-------- + +(1) An Example on a Sparc running SunOS 5.5.1 using TCP as the underlying transport + + + On the host lambada.cs.wustl.edu : + + % ./server tpool cool-tcp://lambada.cs.wustl.edu:3000 -v -cool-tcp -cool-iiop + + On the host merengue.cs.wustl.edu : + + % ./client -t 2 -h lambada.cs.wustl.edu -p 3000 -cool-tcp -cool-iiop + + The output of the client program may look like this: + + (5) Everyone's done, here I go!! + (4) Threads have bound, utilization test started + (9) Everyone's done, here I go!! + (8) Everyone's done, here I go!! + (6) Everyone's done, here I go!! + (7) Everyone's done, here I go!! + cube average call ACE_OS::time = 20.917016 msec, 47.807966 calls/second + (5) My latency was 20.917016 + 5 calls, 0 errors + cube average call ACE_OS::time = 19.299501 msec, 51.814811 calls/second + (8) My latency was 19.299501 + cube average call ACE_OS::time = 19.262436 msec, 51.914514 calls/second + 5 calls, 0 errors + (9) My latency was 19.262436 + 5 calls, 0 errors + cube average call ACE_OS::time = 15.101540 msec, 66.218412 calls/second + (6) My latency was 15.101540 + 5 calls, 0 errors + cube average call ACE_OS::time = 10.320359 msec, 96.895858 calls/second + (7) My latency was 10.320359 + 5 calls, 0 errors + Test done. + High priority client latency : 20.917016 msec, jitter: 36.582330 msec + Low priority client latency : 15.995959 msec, jitter: 527.515277 msec + utilization task performed 435 computations + +(2) An Example on a MVME177 backplane using 68k processors running ClassiX using + Chorus IPC as the underlying transport + + + On the host tambora2.cs.wustl.edu : + + % rsh tambora2 arun /tests/Cubit/COOL/MT_Cubit/server tpool cool-chorus://:1023 -v -cool-chorus + + On the host tambora1.cs.wustl.edu : + + % rsh tambora1 arun /tests/Cubit/COOL/MT_Cubit/client -n 400 -I -t 2 -p 1023 -cool-chorus + + The output of the client program might look like this: + + started aid = 12 + COOL:0000000001000000010000001C00750AA60000000200750AA65555555500000001429A00000000000A(13) Thread created + (13) Im the high priority client, my id is 0. + Using ior = cool-chorus://:1023 + Creating 1 clients with low priority of 125 + (13) Binding succeeded + (13) Cb == 2c6144 + Object Created at: '2908484l'connected to object 'COOL:0000000001000000010000001C00750AA60000000200750AA65555555500000001429A00000000000A' + COOL:0000000001000000010000001C00750AA60000000200750AA65555555500000001429A00000000000A + (13) Waiting for other threads to finish binding.. + (12) Thread created + (12) Im a low priority client, my id is 1 + Using ior = cool-chorus://:1023 + (12) Binding succeeded + (12) Cb == 2c6164 + Object Created at: '2908516l'connected to object 'COOL:0000000001000000010000001C00750AA60000000200750AA65555555500000001429A00000000000A'(12) Waiting for other threads to finish binding.. + (13) Everyone's done, here I go!! + (12) Everyone's done, here I go!! + (12|13) cube average call ACE_OS::time = 12835 usec, 77 calls/second + (13) My latency was 12835 + 400 calls, 0 errors + (12|12) cube average call ACE_OS::time = 12931 usec, 77 calls/second + (12) My latency was 12931 + Test done. + High priority client latency : 12835 usec + Low priority client latency : 12931 usec + 400 calls, 0 errors + --->Output file for latency data is "cb12__2.txt" + (8) utilization task performed 0 computations diff --git a/TAO/performance-tests/Cubit/COOL/MT_Cubit/Task_Client.cpp b/TAO/performance-tests/Cubit/COOL/MT_Cubit/Task_Client.cpp new file mode 100644 index 00000000000..86db2f4e172 --- /dev/null +++ b/TAO/performance-tests/Cubit/COOL/MT_Cubit/Task_Client.cpp @@ -0,0 +1,629 @@ +// $Id$ + +#include "Task_Client.h" + +ACE_RCSID(MT_Cubit, Task_Client, "$Id$") + +Task_State::Task_State (int argc, char **argv) + : start_count_ (0), + loop_count_ (5), + thread_count_ (5), + base_port_ (5000), + datatype_ (CB_OCTET), + argc_ (argc), + argv_ (argv), + thread_per_rate_ (0), + global_jitter_array_ (0), + use_chorus_ipc_ (0), + grain_ (1) +{ + int c; + int datatype; + + // defaults + ACE_OS::strcpy (server_host_, "localhost"); + ior_header_ = ACE_OS::strdup ("cool-tcp"); + ACE_Get_Opt opts (argc, argv, "Hh:n:t:p:d:rIg:"); + + while ((c = opts ()) != -1) + switch (c) { + case 'g': + grain_ = ACE_OS::atoi (opts.optarg); + if (grain_ < 1) + grain_ = 1; + break; + case 'I': + use_chorus_ipc_ = 1; + break; + case 'r': + thread_per_rate_ = 1; + break; + case 'd': + datatype = ACE_OS::atoi (opts.optarg); + switch (datatype) + { + case CB_OCTET: + ACE_DEBUG ((LM_DEBUG, "Testing Octets\n")); + datatype_ = CB_OCTET; + break; + case CB_LONG: + ACE_DEBUG ((LM_DEBUG, "Testing Longs\n")); + datatype_ = CB_LONG; + break; + case CB_STRUCT: + ACE_DEBUG ((LM_DEBUG, "Testing Structs\n")); + datatype_ = CB_STRUCT; + break; + case CB_SHORT: + default: + ACE_DEBUG ((LM_DEBUG, "Testing Shorts\n")); + datatype_ = CB_SHORT; + break; + } + continue; + case 'h': + ACE_OS::strcpy (server_host_, opts.optarg); + continue; + case 'p': + base_port_ = ACE_OS::atoi (opts.optarg); + continue; + case 'n': // loop count + loop_count_ = (u_int) ACE_OS::atoi (opts.optarg); + continue; + case 't': + thread_count_ = (u_int) ACE_OS::atoi (opts.optarg); + continue; + case 'H': + ACE_DEBUG ((LM_DEBUG, "usage: %s" + "[-d datatype Octet=0, Short=1, Long=2, Struct=3]" + " [-n num_calls]" + " [-h server_hostname]" + " [-p server_port_num]" + " [-t num_threads]" + " [-I Use Chorus IPC. (For Chorus ClassiX *only*) ]" + " [-g granularity_of_request_timing]" + "\n", argv [0])); + continue; + } + + if (use_chorus_ipc_ == 1) + { + ior_header_ = ACE_OS::strdup ("cool-chorus"); + ACE_OS::strcpy (server_host_, ""); + } + + // thread_count_ + 1 because there is one utilization thread also + // wanting to begin at the same time the clients begin.. + ACE_NEW (barrier_, ACE_Barrier (thread_count_ + 1)); + ACE_NEW (latency_, double [thread_count_]); + ACE_NEW (global_jitter_array_, double *[thread_count_]); +} + +Client::Client (Task_State *ts) + : ACE_Task<ACE_MT_SYNCH> (ACE_Thread_Manager::instance ()), + ts_ (ts) +{ +} + +void +Client::put_latency (double *jitter, double latency, u_int thread_id) +{ + ACE_MT (ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, ts_->lock_)); + + ts_->latency_[thread_id] = latency; + ts_->global_jitter_array_ [thread_id] = jitter; + +#if defined (ACE_LACKS_FLOATING_POINT) + ACE_DEBUG ((LM_DEBUG, + "(%t) My latency was %u\n", + latency)); +#else + ACE_DEBUG ((LM_DEBUG, + "(%t) My latency was %f\n", + latency)); +#endif /* ! ACE_LACKS_FLOATING_POINT */ +} + +double +Client::get_high_priority_latency (void) +{ + return (double) ts_->latency_ [0]; +} + +double +Client::get_low_priority_latency (void) +{ + double l = 0; + + for (u_int i = 1; i < ts_->start_count_; i++) + l += (double) ts_->latency_[i]; + return ts_->start_count_ > 1? l / (double) (ts_->start_count_ - 1) : 0; +} + +int +Client::get_latency (u_int thread_id) +{ + return ts_->latency_ [thread_id]; +} + +double +Client::get_high_priority_jitter (void) +{ + double jitter = 0; + double average = get_high_priority_latency (); + + // Compute the standard deviation (i.e. jitter) from the values + // stored in the global_jitter_array_. + + // we first compute the sum of the squares of the differences + // each latency has from the average + for (u_int i = 0; i < ts_->loop_count_; i ++) + { + double difference = + ts_->global_jitter_array_ [0][i] - average; + jitter += difference * difference; + } + + // Return the square root of the sum of the differences computed + // above, i.e. jitter. + return sqrt (jitter); +} + +double +Client::get_low_priority_jitter (void) +{ + double jitter = 0; + double average = get_low_priority_latency (); + + // Compute the standard deviation (i.e. jitter) from the values + // stored in the global_jitter_array_. + + // We first compute the sum of the squares of the differences each + // latency has from the average. + for (u_int j = 1; j < ts_->start_count_; j ++) + for (u_int i = 0; i < ts_->loop_count_; i ++) + { + double difference = ts_->global_jitter_array_ [j][i] - average; + jitter += difference * difference; + } + + // Return the square root of the sum of the differences computed + // above, i.e. jitter. + return sqrt (jitter); +} + +int +Client::svc (void) +{ + ACE_DEBUG ((LM_DEBUG, + "(%t) Thread created\n")); + + u_int thread_id; + Cubit_ptr cb; + char ior [1024]; + double frequency; + CORBA::ORB_ptr orb_ptr; + + { + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, ts_->lock_, -1); + + thread_id = ts_->start_count_; + ts_->start_count_++; + + if (ts_->thread_per_rate_ == 0) + { + if (thread_id == 0) + { + ACE_DEBUG ((LM_DEBUG, + "(%t) Im the high priority client, my id is %d.\n", + thread_id)); + ACE_OS::sprintf (ior, + "%s://%s:%d", + ts_->ior_header_, + ts_->server_host_, + ts_->base_port_); + frequency = CB_HIGH_PRIORITY_RATE; + } + else + { + ACE_DEBUG ((LM_DEBUG, + "(%t) Im a low priority client, my id is %d\n", + thread_id)); + ACE_OS::sprintf (ior, + "%s://%s:%d", + ts_->ior_header_, + ts_->server_host_, + ts_->base_port_);// + thread_id); + frequency = CB_LOW_PRIORITY_RATE; + } + } + else + { + switch (thread_id) + { +///////////////////////////////////// +// THIS NEEDS TO BE UPDATED AS ABOVE. +///////////////////////////////////// + case CB_40HZ_CONSUMER: + ACE_DEBUG ((LM_DEBUG, "(%t) Im the high priority client, my id is %d.\n", thread_id)); + ::sprintf (ior, "cool-tcp://%s:%d", ts_->server_host_, ts_->base_port_); + frequency = CB_40HZ_CONSUMER_RATE; + break; + case CB_20HZ_CONSUMER: + ACE_DEBUG ((LM_DEBUG, "(%t) Im the high priority client, my id is %d.\n", thread_id)); + ::sprintf (ior, "cool-tcp://%s:%d", ts_->server_host_, ts_->base_port_);//+1); + frequency = CB_20HZ_CONSUMER_RATE; + break; + case CB_10HZ_CONSUMER: + ACE_DEBUG ((LM_DEBUG, "(%t) Im the high priority client, my id is %d.\n", thread_id)); + ::sprintf (ior, "cool-tcp://%s:%d", ts_->server_host_, ts_->base_port_);//+2); + frequency = CB_10HZ_CONSUMER_RATE; + break; + case CB_5HZ_CONSUMER: + ACE_DEBUG ((LM_DEBUG, "(%t) Im the high priority client, my id is %d.\n", thread_id)); + ::sprintf (ior, "cool-tcp://%s:%d", ts_->server_host_, ts_->base_port_);//+3); + frequency = CB_5HZ_CONSUMER_RATE; + break; + case CB_1HZ_CONSUMER: + ACE_DEBUG ((LM_DEBUG, "(%t) Im the high priority client, my id is %d.\n", thread_id)); + ::sprintf (ior, "cool-tcp://%s:%d", ts_->server_host_, ts_->base_port_);//+4); + frequency = CB_1HZ_CONSUMER_RATE; + break; + default: + ACE_DEBUG ((LM_DEBUG, "(%t) Invalid Thread ID.\n", thread_id)); + } + } /* else */ + + ACE_DEBUG ((LM_DEBUG, "Using ior = %s\n", ior)); + + CORBA::Object_ptr objref = CORBA::Object::_nil (); + CORBA::Environment env; + + orb_ptr = CORBA::ORB_init (ts_->argc_, ts_->argv_, 0, env); + + if (env.exception () != 0) + ACE_ERROR_RETURN ((LM_ERROR,"%s:ORB initialization", env.exception ()), 2); + + // CORBA_BOA_ptr oa_ptr = orb_ptr->OA_init (ts_->argc_, ts_->argv_, 0, env); + // + // if (oa_ptr == 0) + // ACE_ERROR_RETURN ((LM_ERROR, + // " (%P|%t) Unable to initialize the POA.\n"), + // 1); + + + // + // Initialize client's binding to an + // arbitrary cubit server (at some host) + // + COOL::EOABindingData bindingData (ior); + + cb = Cubit::_bind(bindingData, env); + + // objref = orb_ptr->string_to_object ((CORBA::String) ior, env); + + // if (env.exception () != 0) + // ACE_ERROR_RETURN ((LM_ERROR, + // "%s:string2object failed. Supply valid IOR with the -O option\n", + // env.exception ()), 2); + + // if (CORBA::is_nil (objref) == CORBA_TRUE) + // ACE_ERROR_RETURN ((LM_ERROR, + // "%s: must identify non-null target objref\n", + // ts_->argv_ [0]), + // 1); + + // Narrow the CORBA::Object reference to the stub object, checking + // the type along the way using _is_a. + // cb = Cubit::_narrow (objref); + + if ( (CORBA::is_nil (cb) == CORBA_TRUE) || (env.exception () != 0)) + { + ACE_ERROR_RETURN ((LM_ERROR, "%s:Create cubit failed\n", env.exception ()), 1); + } + ACE_DEBUG ((LM_DEBUG, "(%t) Binding succeeded\n")); + ACE_DEBUG ((LM_DEBUG, "(%t) Cb == %x\n", cb)); + + CORBA::String str; + + str = orb_ptr->object_to_string (cb, env); + + if (env.exception () != 0) + ACE_ERROR_RETURN ((LM_ERROR, "object_to_string %s\n", env.exception ()), -1); + + ACE_OS::puts ((char *) str); + ACE_OS::fflush (stdout); + ACE_DEBUG ((LM_DEBUG, "Object Created at: '%ul'", cb)); + ACE_DEBUG ((LM_DEBUG, "connected to object '%s'", str)); + } + + ACE_DEBUG ((LM_DEBUG, "(%t) Waiting for other threads to finish binding..\n")); + ts_->barrier_->wait (); + ACE_DEBUG ((LM_DEBUG, "(%t) Everyone's done, here I go!!\n")); + + this->run_tests (cb, ts_->loop_count_, thread_id, ts_->datatype_, frequency); + + // Free resources + // CORBA::release (orb_ptr); + + return 0; +} + +int +Client::run_tests (Cubit_ptr cb, + u_int loop_count, + u_int thread_id, + Cubit_Datatypes datatype, + double frequency) +{ + CORBA::Environment env; + u_int i = 0; + u_int call_count = 0, error_count = 0; + double *my_jitter_array; + ACE_NEW_RETURN (my_jitter_array, double [ts_->loop_count_], 1); + + double latency = 0; + double sleep_time = (1/frequency) * (1000 * 1000); + double delta = 0; + + int pstartTime = 0; + int pstopTime = 0; + double real_time = 0.0; + +#if defined (USE_QUANTIFY) + quantify_stop_recording_data(); + quantify_clear_data (); +#endif /* USE_QUANTIFY */ + + // Make the calls in a loop. + for (i = 0; i < loop_count; i++) + { + ACE_High_Res_Timer timer_; + ACE_Time_Value tv (0, (long int) (sleep_time - delta)); + ACE_OS::sleep (tv); + + // Elapsed time will be in microseconds. + ACE_Time_Value delta_t; + +#if defined (CHORUS) + pstartTime = pccTime1Get(); +#else /* CHORUS */ + timer_.start (); +#endif /* !CHORUS */ + + switch (datatype) + { + case CB_OCTET: + { + // Cube an octet. + CORBA::Octet arg_octet = func (i), ret_octet = 0; + +#if defined (USE_QUANTIFY) + /* start recording quantify data from here */ + quantify_start_recording_data (); +#endif /* USE_QUANTIFY */ + ret_octet = cb->cube_octet (arg_octet, env); + +#if defined (USE_QUANTIFY) + quantify_stop_recording_data(); +#endif /* USE_QUANTIFY */ + + 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,"%s:Call failed\n", env.exception ()), 2); + } + + arg_octet = arg_octet * arg_octet * arg_octet; + + if (arg_octet != ret_octet) + { + ACE_DEBUG ((LM_DEBUG, "** cube_octet(%d) (--> %d)\n", arg_octet , ret_octet)); + error_count++; + } + call_count++; + } + break; + + case CB_SHORT: + // Cube a short. + { + call_count++; + + CORBA::Short arg_short = func (i), ret_short; + +#if defined (USE_QUANTIFY) + // start recording quantify data from here. + quantify_start_recording_data (); +#endif /* USE_QUANTIFY */ + + ret_short = cb->cube_short (arg_short, env); + +#if defined (USE_QUANTIFY) + quantify_stop_recording_data(); +#endif /* USE_QUANTIFY */ + + if (env.exception () != 0) + ACE_ERROR_RETURN ((LM_ERROR, + "%s:Call failed\n", + env.exception ()), + 2); + + arg_short = arg_short * arg_short * arg_short; + + if (arg_short != ret_short) + { + ACE_DEBUG ((LM_DEBUG, "** cube_short(%d) (--> %d)\n", arg_short , ret_short)); + error_count++; + } + break; + } + // Cube a long. + + case CB_LONG: + { + call_count++; + + CORBA::Long arg_long = func (i), ret_long; + +#if defined (USE_QUANTIFY) + // start recording quantify data from here. + quantify_start_recording_data (); +#endif /* USE_QUANTIFY */ + + ret_long = cb->cube_long (arg_long, env); + +#if defined (USE_QUANTIFY) + quantify_stop_recording_data(); +#endif /* USE_QUANTIFY */ + + if (env.exception () != 0) + ACE_ERROR_RETURN ((LM_ERROR,"%s:Call failed\n", env.exception ()), 2); + + arg_long = arg_long * arg_long * arg_long; + + if (arg_long != ret_long) + { + ACE_DEBUG ((LM_DEBUG, "** cube_long(%d) (--> %d)\n", arg_long , ret_long)); + error_count++; + } + break; + } + + case CB_STRUCT: + // Cube a "struct" ... + { + Cubit::Many arg_struct, ret_struct; + + call_count++; + + arg_struct.l = func (i); + arg_struct.s = func (i); + arg_struct.o = func (i); + +#if defined (USE_QUANTIFY) + // start recording quantify data from here. + quantify_start_recording_data (); +#endif /* USE_QUANTIFY */ + + ret_struct = cb->cube_struct (arg_struct, env); + +#if defined (USE_QUANTIFY) + quantify_stop_recording_data(); +#endif /* USE_QUANTIFY */ + + if (env.exception () != 0) + ACE_ERROR_RETURN ((LM_ERROR,"%s:Call failed\n", env.exception ()), 2); + + arg_struct.l = arg_struct.l * arg_struct.l * arg_struct.l ; + arg_struct.s = arg_struct.s * arg_struct.s * arg_struct.s ; + arg_struct.o = arg_struct.o * arg_struct.o * arg_struct.o ; + + if (arg_struct.l != ret_struct.l + || arg_struct.s != ret_struct.s + || arg_struct.o != ret_struct.o ) + { + ACE_DEBUG ((LM_DEBUG, "**cube_struct error!\n")); + error_count++; + } + + break; + } + } + + // use sysBench when CHORUS defined and option specified on command line +#if defined (CHORUS) + if ( (loop_count % ts_->grain_) == 0) + pstopTime = pccTime1Get(); +#else /* CHORUS */ + // if CHORUS is not defined just use plain timer_.stop (). + timer_.stop (); + timer_.elapsed_time (delta_t); +#endif /* !CHORUS */ + + // Calculate time elapsed +#if defined (ACE_LACKS_FLOATING_POINT) +# if defined (CHORUS) + real_time = pstopTime - pstartTime; + my_jitter_array [i/ts_->grain_] = real_time; // in units of microseconds. + // update the latency array, correcting the index using the granularity +# else /* CHORUS */ + // Store the time in usecs. + real_time = delta_t.sec () * ACE_ONE_SECOND_IN_USECS + + delta_t.usec (); + my_jitter_array [i] = real_time; // in units of microseconds. +# endif /* !CHORUS */ + delta = ((40 * fabs (real_time) / 100) + (60 * delta / 100)); // pow(10,6) + latency += real_time; +#else /* ACE_LACKS_FLOATING_POINT */ + // Store the time in secs. + real_time = delta_t.sec () + (double)delta_t.usec () / ACE_ONE_SECOND_IN_USECS; + delta = ((0.4 * fabs (real_time * (1000 * 1000))) + (0.6 * delta)); // pow(10,6) + latency += real_time; + my_jitter_array [i] = real_time * 1000; +#endif /* !ACE_LACKS_FLOATING_POINT */ + } + + if (call_count > 0) + { + if (error_count == 0) + { +#if defined (ACE_LACKS_FLOATING_POINT) + double calls_per_second = (call_count * ACE_ONE_SECOND_IN_USECS) / latency; +#endif /* ACE_LACKS_FLOATING_POINT */ + + latency /= call_count; + + if (latency > 0) + { +#if defined (ACE_LACKS_FLOATING_POINT) + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) cube average call ACE_OS::time\t= %u usec, \t" + "%u calls/second\n", + latency, + calls_per_second)); + + this->put_latency (my_jitter_array, + latency, + thread_id); +#else + ACE_DEBUG ((LM_DEBUG, "(%P|%t) cube average call ACE_OS::time\t= %f msec, \t" + "%f calls/second\n", + latency * 1000, + 1 / latency)); + this->put_latency (my_jitter_array, + latency * 1000, + thread_id); +#endif /* ! ACE_LACKS_FLOATING_POINT */ + } + else + { + // still we have to call this function to store a valid array pointer. + this->put_latency (my_jitter_array, + 0, + thread_id); + ACE_DEBUG ((LM_DEBUG, + "*** Warning: Latency is less than or equal to zero." + " Precision may have been lost.\n")); + } + } + ACE_DEBUG ((LM_DEBUG, + "%d calls, %d errors\n", + call_count, + error_count)); + } + + // cb->please_exit (env); + return 0; +} diff --git a/TAO/performance-tests/Cubit/COOL/MT_Cubit/Task_Client.h b/TAO/performance-tests/Cubit/COOL/MT_Cubit/Task_Client.h new file mode 100644 index 00000000000..5b04c3a73b5 --- /dev/null +++ b/TAO/performance-tests/Cubit/COOL/MT_Cubit/Task_Client.h @@ -0,0 +1,191 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// TAO/tests +// +// = FILENAME +// Task_Client.h +// +// = AUTHOR +// Andy Gokhale, Sumedh Mungee and Sergio Flores-Gaitan +// +// ============================================================================ + +#if !defined (TASK_CLIENT_H) +#define TASK_CLIENT_H + +#include <corba/cool.H> +#include "api/api.H" +#include "cubit.H" + +#include "ace/Synch.h" +#include "ace/Task.h" +#include "ace/Thread_Manager.h" +#include "ace/Get_Opt.h" +#include "ace/Profile_Timer.h" +#include <math.h> + +#if defined (CHORUS) +#include "pccTimer.h" +#endif /* CHORUS */ + +// @@ Should we put this into a more general file, e.g., OS.h? +// +// I will integrate this, together with the sqrt() function when +// the implementation is complete. --Sergio. +// @@ Sergio, can you please use the ACE_timer_t here rather than #define'ing double? +#if defined (ACE_LACKS_FLOATING_POINT) +#define double ACE_UINT32 +#define fabs(X) ((X) >= 0 ? (X) : -(X)) +// the following is just temporary, until we finish the sqrt() +// implementation. +#define sqrt(X) (1) +#endif /* ACE_LACKS_FLOATING_POINT */ + +// Arbitrary generator used by the client to create the numbers to be +// cubed. +inline int +func (unsigned i) +{ + return i - 117; +} + +// The various datatypes which the client and the server can exchange. +enum Cubit_Datatypes +{ + CB_OCTET, + CB_SHORT, + CB_LONG, + CB_STRUCT +}; + +const int CB_40HZ_CONSUMER = 0; +const int CB_20HZ_CONSUMER = 1; +const int CB_10HZ_CONSUMER = 2; +const int CB_5HZ_CONSUMER = 3; +const int CB_1HZ_CONSUMER = 4; + +const int CB_40HZ_CONSUMER_RATE = 40; +const int CB_20HZ_CONSUMER_RATE = 20; +const int CB_10HZ_CONSUMER_RATE = 10; +const int CB_5HZ_CONSUMER_RATE = 5; +const int CB_1HZ_CONSUMER_RATE = 1; + +const int CB_HIGH_PRIORITY_RATE = 20; +const int CB_LOW_PRIORITY_RATE = 10; + +class Task_State + // = TITLE + // Maintains state common to multiple Cubit clients + + // = DESCRIPTION + // This class maintains state which is common to the potentially + // multiple concurrent clients. +{ +public: + ACE_Barrier *barrier_; + // Barrier for the multiple clients to synchronize after + // binding to the servants. + + Task_State (int argc, char **argv); + // Constructor. Takes the command line arguments, which are + // later passed into ORB_init + + u_int start_count_; + // keeps a count of the number of clients started.. This + // count also serves as a thread-id. The first thread created + // gets an ID of 0, then 1, and so on.. + + u_int loop_count_; + // number of times to loop, making calls.. + + u_int thread_count_; + // number of concurrent clients to create.. + + u_int base_port_; + // this is the port at which the high priority servant is + // listening.. lower priority ports begin at base_port_ + 1 + + char server_host_ [1024]; + // Server hostname + + double *latency_; + // Array to store the latency for every client, indexed by + // thread-id. + + Cubit_Datatypes datatype_; + // Which datatype to use to make the calls + + ACE_Thread_Mutex lock_; + // lock to protect access to this object + + int argc_; + char **argv_; + // command line arguments + + u_int thread_per_rate_; + // Flag for the thread_per_rate test + + double **global_jitter_array_; + // this array stores the latency seen by each client for each + // request, to be used later to compute jitter + + u_int use_chorus_ipc_; + // flag that indicates that we are going to use Chorus IPC + // communication mechanism, instead of the TCP/IP protocol stack. + // This only applies to the CHORUS ClassiX OS. + + char * ior_header_; + // pointer to the ior part where you specify the type of transport + // for COOL (i.e. ipc or tcp) + + u_int grain_; + // this is the granularity of the timing of the CORBA requests. A + // value of 5 represents that we will take time every 5 requests, + // instead of the default of every request (1). +}; + +class Client : public ACE_Task<ACE_MT_SYNCH> + // = TITLE + // The Cubit client. +{ +public: + Client (Task_State *ts); + // constructor, with a pointer to the common task state. + + virtual int svc (void); + // the thread function + + double get_high_priority_latency (void); + double get_low_priority_latency (void); + double get_high_priority_jitter (void); + double get_low_priority_jitter (void); + int get_latency (u_int thread_id); + // accessors to get the various measured quantities + + +private: + + int run_tests (Cubit_ptr, + unsigned int, + unsigned int, + Cubit_Datatypes, + double frequency); + // makes the calls to the servant + + void put_latency (double *jitter, + double latency, + unsigned int); + // Records the latencies in the Task_State + + int parse_args (int, char **); + // parses the arguments + + Task_State *ts_; + // pointer to shared state + +}; + +#endif /* !defined (TASK_CLIENT_H) */ diff --git a/TAO/performance-tests/Cubit/COOL/MT_Cubit/Util_Thread.cpp b/TAO/performance-tests/Cubit/COOL/MT_Cubit/Util_Thread.cpp new file mode 100644 index 00000000000..5a63a86339c --- /dev/null +++ b/TAO/performance-tests/Cubit/COOL/MT_Cubit/Util_Thread.cpp @@ -0,0 +1,62 @@ +// $Id$ + +#include "Util_Thread.h" + +ACE_RCSID(MT_Cubit, Util_Thread, "$Id$") + +Util_Thread::Util_Thread (Task_State *ts, + ACE_Thread_Manager *thr_mgr) + : ACE_Task<ACE_MT_SYNCH> (thr_mgr), + done_ (0), + number_of_computations_ (0), + ts_ (ts) +{ +} + +int +Util_Thread::svc (void) +{ + ACE_DEBUG ((LM_DEBUG, + "(%t) Utilization Thread created, " + "waiting for threads to finish binding\n")); + + // this barrier synchronizes the utilization thread with + // the client threads + // i.e., the Util_thread should wait until all the + // clients have finished binding, and only then + // start measuring the utilization. + this->ts_->barrier_->wait (); + + ACE_DEBUG ((LM_DEBUG, + "(%t) Threads have bound, " + "utilization test started\n")); + + this->run_computations (); + return 0; +} + +double +Util_Thread::get_number_of_computations (void) +{ + return this->number_of_computations_; +} + +// Perform repeated prime factor computations on an arbitrary number. +// And you thought your life was boring... :-) + +int +Util_Thread::run_computations (void) +{ + while (this->done_ == 0) + { + // See if this number is prime. 2 and CUBIT_ARBIT_NUMBER / 2 are + // the recommended values for min_factor and max_factor, as + // explained in ACE.h (is_prime). + ACE::is_prime (CUBIT_ARBIT_NUMBER, + 2, + CUBIT_ARBIT_NUMBER / 2); + this->number_of_computations_ ++; + } + + return 0; +} diff --git a/TAO/performance-tests/Cubit/COOL/MT_Cubit/Util_Thread.h b/TAO/performance-tests/Cubit/COOL/MT_Cubit/Util_Thread.h new file mode 100644 index 00000000000..b336c11c2de --- /dev/null +++ b/TAO/performance-tests/Cubit/COOL/MT_Cubit/Util_Thread.h @@ -0,0 +1,45 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// TAO/tests +// +// = FILENAME +// Util_Thread.h +// +// = AUTHOR +// Andy Gokhale, Sumedh Mungee, and Sergio Flores-Gaitan +// +// ============================================================================ + +#include "Task_Client.h" + +const int CUBIT_ARBIT_NUMBER = 2064885; + +class Util_Thread : public ACE_Task<ACE_MT_SYNCH> + // = TITLE + // The thread that computes utilization. +{ +public: + Util_Thread (Task_State *, + ACE_Thread_Manager *thr_mgr); + // constructor. + + virtual int svc (void); + // The thread entry point function. + + double get_number_of_computations (void); + // Gets the number of computations the thread was able to perform. + + int done_; + // Indicates whether we're done. + +private: + int run_computations (void); + // Run the computations. + + // Sumedh, please add comments here. + double number_of_computations_; + Task_State *ts_; +}; diff --git a/TAO/performance-tests/Cubit/COOL/MT_Cubit/client.cpp b/TAO/performance-tests/Cubit/COOL/MT_Cubit/client.cpp new file mode 100644 index 00000000000..0a1dbcc474c --- /dev/null +++ b/TAO/performance-tests/Cubit/COOL/MT_Cubit/client.cpp @@ -0,0 +1,289 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// TAO/tests +// +// = FILENAME +// client.cpp +// +// = AUTHOR +// Andy Gokhale, Brian Mendel, Sumedh Mungee, and Sergio Flores-Gaitan +// +// ============================================================================ + +#include "client.h" + +ACE_RCSID(MT_Cubit, client, "$Id$") + +int +initialize (void) +{ +#if defined (VXWORKS) + hostAdd ("mv2604d", "130.38.183.132"); +#if defined (VME_DRIVER) + STATUS status = vmeDrv (); + if (status != OK) + printf ("ERROR on call to vmeDrv()\n"); + status = vmeDevCreate ("/vme"); + if (status != OK) + printf ("ERROR on call to vmeDevCreate()\n"); +#endif /* defined (VME_DRIVER) */ +#endif /* defined (VXWORKS) */ + + // Make sure we've got plenty of socket handles. This call will use + // the default maximum. + ACE::set_handle_limit (); + return 0; +} + +int +do_priority_inversion_test (Task_State &ts) +{ + u_int i = 0; + + // Create the clients + Client high_priority_client (&ts); + Client low_priority_client (&ts); + + // Create the daemon thread in its own <ACE_Thread_Manager>. + ACE_Thread_Manager thr_mgr; + + Util_Thread util_thread (&ts, &thr_mgr); + + ACE_Sched_Priority priority = + ACE_Sched_Params::priority_min (ACE_SCHED_FIFO, + ACE_SCOPE_THREAD); + + // First activate the Utilization thread. It will wait until all + // threads have finished binding. + util_thread.activate (THR_BOUND, + 1, + 0, + priority); + + // Now activate the high priority client. + priority = ACE_THR_PRI_FIFO_DEF; + + if (high_priority_client.activate (THR_BOUND | ACE_SCHED_FIFO, + 1, + 0, + priority) == -1) + ACE_ERROR ((LM_ERROR, + "%p\n", + "activate failed")); + + // Drop the priority, so that the priority of clients will increase + // with increasing client number. + for (i = 0; i < ts.thread_count_; i++) + priority = ACE_Sched_Params::previous_priority (ACE_SCHED_FIFO, + priority, + ACE_SCOPE_THREAD); + + ACE_DEBUG ((LM_DEBUG, + "Creating %d clients with low priority of %d\n", + ts.thread_count_ - 1, + priority)); + + for (i = 0; i < ts.thread_count_ - 1; i++) + { + // The first thread starts at min + 1, since the minimum + // priority thread is the utilization thread. + + if (low_priority_client.activate (THR_BOUND, + 1, + 1, + priority) == -1) + ACE_ERROR ((LM_ERROR, + "%p\n", + "activate failed")); + + // get the next higher priority + priority = ACE_Sched_Params::next_priority (ACE_SCHED_FIFO, + priority, + ACE_SCOPE_THREAD); + } + // Wait for all the threads to exit. + ACE_Thread_Manager::instance ()->wait (); + +#if defined (VXWORKS) + ACE_OS::printf ("Test done.\n" + "High priority client latency : %d usec\n" + "Low priority client latency : %d usec\n", + high_client.get_high_priority_latency (), + low_client.get_low_priority_latency ()); +#elif defined (CHORUS) + ACE_OS::printf ("Test done.\n" + "High priority client latency : %u usec\n" + "Low priority client latency : %u usec\n", + high_priority_client.get_high_priority_latency (), + low_priority_client.get_low_priority_latency ()); + + // output the latency values to a file, tab separated, to import it + // to Excel to calculate jitter, in the mean time we come up with + // the sqrt() function. + FILE *latency_file_handle = 0; + char latency_file[BUFSIZ]; + char buffer[BUFSIZ]; + + ACE_OS::sprintf (latency_file, + "cb__%d.txt", + ts.thread_count_); + + ACE_OS::fprintf(stderr, + "--->Output file for latency data is \"%s\"\n", + latency_file); + + latency_file_handle = ACE_OS::fopen (latency_file, "w"); + + for (u_int j = 0; j < ts.start_count_; j ++) + { + ACE_OS::sprintf(buffer, + "%s #%d", + j==0? "High Priority": "Low Priority", + j); + for (u_int i = 0; i < ts.loop_count_; i ++) + { + ACE_OS::sprintf(buffer+strlen(buffer), + "\t%u\n", + ts.global_jitter_array_[j][i]); + fputs (buffer, latency_file_handle); + buffer[0]=0; + } + } + + ACE_OS::fclose (latency_file_handle); +#else + ACE_DEBUG ((LM_DEBUG, "Test done.\n" + "High priority client latency : %f msec, jitter: %f msec\n" + "Low priority client latency : %f msec, jitter: %f msec\n", + high_priority_client.get_high_priority_latency (), + high_priority_client.get_high_priority_jitter (), + low_priority_client.get_low_priority_latency (), + low_priority_client.get_low_priority_jitter ())); +#endif /* !defined (CHORUS) && !defined (VXWORKS) */ + + // signal the utilization thread to finish with its work.. + util_thread.done_ = 1; + + // This will wait for the utilization thread to finish. + thr_mgr.wait (); + +#if defined (ACE_LACKS_FLOATING_POINT) + ACE_DEBUG ((LM_DEBUG, + "(%t) utilization task performed %u computations\n", + util_thread.get_number_of_computations ())); +#else + ACE_DEBUG ((LM_DEBUG, + "(%t) utilization task performed %g computations\n", + util_thread.get_number_of_computations ())); +#endif /* ! ACE_LACKS_FLOATING_POINT */ + + return 0; + +} + +int +do_thread_per_rate_test (Task_State &ts) +{ + // First activate the high priority client. + Client CB_40Hz_client (&ts); + Client CB_20Hz_client (&ts); + Client CB_10Hz_client (&ts); + Client CB_5Hz_client (&ts); + Client CB_1Hz_client (&ts); + + ACE_Sched_Priority priority = + ACE_Sched_Params::priority_max (ACE_SCHED_FIFO, + ACE_SCOPE_THREAD); + + // VxWorks priority of 0 causes problems. + priority = 10; + ACE_DEBUG ((LM_DEBUG, "Creating 40 Hz client with priority %d\n", priority)); + if (CB_40Hz_client.activate (THR_BOUND, 1, 0, priority++) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "activate failed")); + + ACE_DEBUG ((LM_DEBUG, "Creating 20 Hz client with priority %d\n", priority)); + if (CB_20Hz_client.activate (THR_BOUND, 1, 0, priority++) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "activate failed")); + + ACE_DEBUG ((LM_DEBUG, "Creating 10 Hz client with priority %d\n", priority)); + if (CB_10Hz_client.activate (THR_BOUND, 1, 0, priority++) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "activate failed")); + + ACE_DEBUG ((LM_DEBUG, "Creating 5 Hz client with priority %d\n", priority)); + if (CB_5Hz_client.activate (THR_BOUND, 1, 0, priority++) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "activate failed")); + + ACE_DEBUG ((LM_DEBUG, "Creating 1 Hz client with priority %d\n", priority)); + if (CB_1Hz_client.activate (THR_BOUND, 1, 0, priority++) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "activate failed")); + + // Wait for all the threads to exit. + ACE_Thread_Manager::instance ()->wait (); + + ACE_OS::printf ("Test done.\n" + "40Hz client latency : %d usec\n" + "20Hz client latency : %d usec\n" + "10Hz client latency : %d usec\n" + "5Hz client latency : %d usec\n" + "1Hz client latency : %d usec\n", + CB_40Hz_client.get_latency (0), + CB_20Hz_client.get_latency (1), + CB_10Hz_client.get_latency (2), + CB_5Hz_client.get_latency (3), + CB_1Hz_client.get_latency (4)); + return 0; +} + +// This is the main routine of the client, where we create a high +// priority and a low priority client. we then activate the clients +// with the appropriate priority threads, and wait for them to +// finish. After they aer done, we compute the latency and jitter +// metrics and print them. + +int +main (int argc, char *argv []) +{ +#if defined (FORCE_ARGS) + int argc = 7; + char *argv[] = {"main", + "-d", + "3", // Data Type + "-t", + "10", // Thread Count + "-h", + "mv2604d"}; // Host name +#endif /* defined (FORCE_ARGS) */ + + Task_State ts (argc, argv); + +#if defined (CHORUS) + // start the pccTimer for chorus classix + int pTime; + + // Initialize the PCC timer Chip + pccTimerInit(); + + if(pccTimer(PCC2_TIMER1_START,&pTime) !=K_OK) + { + printf("pccTimer has a pending bench mark\n"); + } +#endif + + if (ts.thread_per_rate_ == 0) + do_priority_inversion_test (ts); + else + do_thread_per_rate_test (ts); + +#if defined (CHORUS) + // stop the pccTimer for chorus ClassiX + if(pccTimer(PCC2_TIMER1_STOP,&pTime) !=K_OK) + { + printf("pccTimer has a pending benchmark\n"); + } +#endif + + return 0; +} diff --git a/TAO/performance-tests/Cubit/COOL/MT_Cubit/client.h b/TAO/performance-tests/Cubit/COOL/MT_Cubit/client.h new file mode 100644 index 00000000000..b4066444a7c --- /dev/null +++ b/TAO/performance-tests/Cubit/COOL/MT_Cubit/client.h @@ -0,0 +1,36 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// TAO/tests +// +// = FILENAME +// client.h +// +// = AUTHOR +// Andy Gokhale, Brian Mendel, Sumedh Mungee, and Sergio Flores-Gaitan +// +// ============================================================================ + +#include <corba/cool.H> +#include "cubit.H" + +#include "ace/Task.h" +#include "ace/Thread_Manager.h" +#include "ace/Get_Opt.h" +#include "ace/Sched_Params.h" + +#include "Task_Client.h" +#include "Util_Thread.h" + +#if defined (CHORUS) +#include "pccTimer.h" +#endif /* CHORUS */ + +#if defined (VME_DRIVER) +#include <hostLib.h> +extern "C" STATUS vmeDrv (void); +extern "C" STATUS vmeDevCreate (char *); +#endif /* defined (VME_DRIVER) */ + diff --git a/TAO/performance-tests/Cubit/COOL/MT_Cubit/cubit.idl b/TAO/performance-tests/Cubit/COOL/MT_Cubit/cubit.idl new file mode 100644 index 00000000000..d4f1610e2a8 --- /dev/null +++ b/TAO/performance-tests/Cubit/COOL/MT_Cubit/cubit.idl @@ -0,0 +1,42 @@ +// $Id$ + +// @(#)cubit.idl 1.1 95/09/10 +// Copyright 1994-1995 by Sun Microsystems, Inc. + +#pragma prefix "Eng.SUN.COM" +#pragma version Cubit 1.1 + +interface Cubit { + octet cube_octet (in octet o); + short cube_short (in short s); + long cube_long (in long l); + + struct Many { + octet o; // + 3 bytes padding (normally) ... + long l; + short s; // + 2 bytes padding (normally) ... + }; + + Many cube_struct (in Many values); + + enum discrim {e_0th, e_1st, e_2nd, e_3rd, e_4th, e_5th}; + + union oneof + switch (discrim) { + // this is an easy union to interpret; no padding + // is needed between discriminant and value. + case e_0th: + octet o; + case e_1st: + short s; + case e_2nd: + long l; + case e_3rd: + default: + Many cm; + }; + + oneof cube_union (in oneof values); + + oneway void please_exit (); +}; diff --git a/TAO/performance-tests/Cubit/COOL/MT_Cubit/cubit_i.cpp b/TAO/performance-tests/Cubit/COOL/MT_Cubit/cubit_i.cpp new file mode 100644 index 00000000000..baf630d7dc5 --- /dev/null +++ b/TAO/performance-tests/Cubit/COOL/MT_Cubit/cubit_i.cpp @@ -0,0 +1,69 @@ +// $Id$ + +#include "cubit_impl.h" +#include "ace/ACE.h" + +ACE_RCSID(MT_Cubit, cubit_impl, "$Id$") + +Cubit_Impl::Cubit_Impl (Task_State *ts) + :ts_ (ts), + util_started_ (0) +{ +} + +CORBA::Octet Cubit_Impl:: cube_octet (CORBA::Octet o, CORBA::Environment &IT_env) +{ + // ACE_DEBUG ((LM_DEBUG, "octet cubed is %d\n", o*o*o)); + if (ts_->run_server_utilization_test_ == 1 && + ts_->utilization_task_started_ == 0 && + this->util_started_ == 0 ) + { + this->util_started_ = 1; + ts_->barrier_->wait (); + } + + ts_->loop_count_++; + + return (CORBA::Octet) (o * o * o); +} + +CORBA::Short Cubit_Impl:: cube_short (CORBA::Short s, CORBA::Environment &IT_env) { + return (CORBA::Short) (s * s * s); +} + +CORBA::Long Cubit_Impl:: cube_long (CORBA::Long l, CORBA::Environment &IT_env) { + return (CORBA::Long) (l * l * l); +} + +Cubit::Many Cubit_Impl:: cube_struct (const Cubit::Many& values, CORBA::Environment &IT_env) { + Cubit::Many out_values; + out_values.o = values.o * values.o * values.o; + out_values.s = values.s * values.s * values.s; + out_values.l = values.l * values.l * values.l; + return out_values; +} + +Cubit::oneof Cubit_Impl:: cube_union (const Cubit::oneof& values, CORBA::Environment &IT_env) { + Cubit::oneof out_values; + switch (values._d ()) { + case Cubit::e_0th: + out_values.o (values.o () * values.o () * values.o ()); + break; + case Cubit::e_1st: + out_values.s (values.s () * values.s () * values.s ()); + break; + case Cubit::e_2nd: + out_values.l (values.l () * values.l () * values.l ()); + break; + case Cubit::e_3rd: + default: + out_values.cm ().o = values.cm ().o * values.cm ().o * values.cm ().o ; + out_values.cm ().s = values.cm ().s * values.cm ().s * values.cm ().s ; + out_values.cm ().l = values.cm ().l * values.cm ().l * values.cm ().l ; + break; + } + return out_values; +} + +void Cubit_Impl:: please_exit (CORBA::Environment &IT_env) { +} diff --git a/TAO/performance-tests/Cubit/COOL/MT_Cubit/cubit_i.h b/TAO/performance-tests/Cubit/COOL/MT_Cubit/cubit_i.h new file mode 100644 index 00000000000..77eecdbbd10 --- /dev/null +++ b/TAO/performance-tests/Cubit/COOL/MT_Cubit/cubit_i.h @@ -0,0 +1,27 @@ +// $Id$ + +#ifndef cubit_ih +#define cubit_ih + +#include <corba/cool.H> +#include "cubit.H" +#include "Task_Client.h" + +class Cubit_Impl { +public: + Cubit_Impl (Task_State *ts); + virtual CORBA_Octet cube_octet (CORBA_Octet o, CORBA_Environment &IT_env=_environment); + virtual CORBA_Short cube_short (CORBA_Short s, CORBA_Environment &IT_env=_environment); + virtual CORBA_Long cube_long (CORBA_Long l, CORBA_Environment &IT_env=_environment); + virtual Cubit::Many cube_struct (const Cubit::Many& values, CORBA_Environment &IT_env=_environment); + virtual Cubit::oneof cube_union (const Cubit::oneof& values, CORBA_Environment &IT_env=_environment); + virtual void please_exit (CORBA_Environment &IT_env=_environment); + +private: + Task_State *ts_; + //pointer to the task state + int util_started_; + // flag to indicate utilization test has started +}; + +#endif diff --git a/TAO/performance-tests/Cubit/COOL/MT_Cubit/pccTimer.cpp b/TAO/performance-tests/Cubit/COOL/MT_Cubit/pccTimer.cpp new file mode 100644 index 00000000000..a8846b631f9 --- /dev/null +++ b/TAO/performance-tests/Cubit/COOL/MT_Cubit/pccTimer.cpp @@ -0,0 +1,281 @@ +// $Id$ + +/* + **************************************************************** + * + * Component = pccTimer.C - mvme167 + * + * Synopsis = + * + * Copyright (c) 1995, 1996, 1997 Chorus systemes + * (R) Chorus is a registered trademark of Chorus systemes + * + **************************************************************** + * + * + **************************************************************** + */ + +/* Everything is relative from +/vobs/chorus_work/merge1/mvme177/appl/include/chorus +*/ + +#include <stdio.h> +#include <chorus.h> +#include <exec/chContext.h> +//#include <exec/c_cpuContext.H> +#include <util/chKnTimeVal.h> +//#include <util/macro.h> +#include <tick/chTick.h> +//#include <kbim/p_chIntr.h> +//#include <stdconsio.h> +#include <bsp/pccchip2.h> +#include <bsp/nvram.h> +#include <bsp/board.h> +#include <exec/chPanic.h> +#include <bsp/intrLevel.h> +#include <timer/chProf.h> +#include <exec/f_chTrap.h> +#include <ims/ims_f.h> +//#include <sched/schedIntf.H> +//#include <p_boardInfo.H> +#include "pccTimer.h" + +ACE_RCSID(MT_Cubit, pccTimer, "$Id$") + + +static unsigned int quartz; +static unsigned int timer_reload_value; +int timerHz = 100; + +volatile struct +pccchip2 *pccchip2 = (volatile struct pccchip2 *) PCCchip2_BASE; + +volatile struct +nvram* nvram = ((volatile struct nvram*)NVRAM_BASE); + + +int +pccTimer(int option, int* uTime) +{ + KnTimeVal time; + + int res = K_EOK; + //option &= ~PCC_USERDATA; + static int benchEnable1 = 0; + static int benchEnable2 = 0; + static unsigned int benchLastTime = 0; + + switch(option) + { + + case PCC2_TIMER1_START: + if (benchEnable1) return K_EINVAL; + benchEnable1 = 1; + pccTimer1Start(); + benchLastTime = pccTimer1Reset(); + break; + + case PCC2_TIMER1_STOP: + benchLastTime = pccTime1Get(); + if (!benchEnable1) return K_EINVAL; + benchEnable1 = 0; + pccTimer1Stop(); + break; + + case PCC2_TIMER1_BPOINT: + benchLastTime = pccTime1Get(); + if (!benchEnable1) return K_EINVAL; + break; + + case PCC2_TIMER2_START: + if (benchEnable2) return K_EINVAL; + benchEnable2 = 1; + pccTimer2Start(); + benchLastTime = pccTimer2Reset(); + break; + + case PCC2_TIMER2_STOP: + benchLastTime = pccTime2Get(); + if (!benchEnable2) return K_EINVAL; + benchEnable2 = 0; + pccTimer2Stop(); + break; + + case PCC2_TIMER2_BPOINT: + benchLastTime = pccTime2Get(); + if (!benchEnable2) return K_EINVAL; + break; + + default: + return K_EINVAL; + } + + // Here only is last time must be returned + if (uTime) + { + *uTime = benchLastTime; + } + + return res; +} + + + // + // Return the value of the timer counter, in microseconds. + // + unsigned int +pccTime1Get() +{ + return pccchip2->timer1cnt; +} + + unsigned int +pccTimer1Reset() +{ + pccchip2->timer1cnt = 0; + return pccchip2->timer1cnt; +} + + void +pccTimer1Start() +{ + unsigned int temp; + + // Clear the counter + pccchip2->timer1cnt = 0; + // Start the counter running + // Do not reset the counter when it matches the compare register (~PCC2_COC) + // Clear the overflow counter + temp = pccchip2->timer1ctl; + pccchip2->timer1ctl = temp | PCC2_COVF | ~PCC2_COC | PCC2_CEN; + +} + + void +pccTimer1Stop() +{ + unsigned int temp; + + // Stop the counter running + temp = pccchip2->timer1ctl; + pccchip2->timer1ctl = temp | ~PCC2_CEN; + +} + + + // + // Return the value of the timer counter, in microseconds. + // + unsigned int +pccTime2Get() +{ + return pccchip2->timer2cnt; +} + + unsigned int +pccTimer2Reset() +{ + pccchip2->timer2cnt = 0; + return pccchip2->timer2cnt; +} + + void +pccTimer2Start() +{ + unsigned int temp; + + // Clear the counter + pccchip2->timer2cnt = 0; + // Start the counter running + // Do not reset the counter when it matches the compare register (~PCC2_COC) + // Clear the overflow counter + temp = pccchip2->timer2ctl; + pccchip2->timer2ctl = temp | PCC2_COVF | ~PCC2_COC | PCC2_CEN; + +} + + void +pccTimer2Stop() +{ + unsigned int temp; + + // Stop the counter running + temp = pccchip2->timer2ctl; + pccchip2->timer2ctl = temp | ~PCC2_CEN; + +} + + // + // Init the PCC2 timer + // + void +pccTimerInit() +{ + volatile unsigned int temp; + char c; + + /* compute board quartz frequency from nvram information */ + c = nvram->config_rom.speed[0]; + quartz = ((unsigned int) c - (unsigned int) '0') * 10; + c = nvram->config_rom.speed[1]; + quartz += ((unsigned int) c - (unsigned int) '0'); + + /* Step 1. Initialize prescaler control register */ + /* On a mvme177, the VME2Chip runs at half the MPU speed */ + temp = pccchip2->prescaleadjust & 0xFFFFFF00; + + switch(quartz) { + case 60 : pccchip2->prescaleadjust = temp | 0x000000E2; /* 256-30 */ + // ASSERT(((BoardInfo*)chorusContext->ctxBoardInfo)->boardId + // == BOARD_MVME177); + break; + default : { + char tab [80]; + printf(tab,"%s : %d", "Unknown clock frequency", quartz); + svSysPanic(KP_DEBUG, 0, 0, tab, __FILE__, __LINE__); + } + } + + timer_reload_value = 1000000 / timerHz; + + + /* Step 2. Set pcc timer 1 and timer 2 compare register */ +// pccchip2->timer1cmp = timer_reload_value; + pccchip2->timer1cmp = ~0; + pccchip2->timer2cmp = ~0; + + + /* Step 3. Clear timer 1 and timer 2 counter register */ + pccchip2->timer1cnt = 0; + pccchip2->timer2cnt = 0; + + + /* Step 4. Enable pcc timer 1 and timer 2*/ + temp = pccchip2->timer1ctl; + pccchip2->timer1ctl = temp | PCC2_COVF | PCC2_COC | PCC2_CEN; + + temp = pccchip2->timer2ctl; + pccchip2->timer2ctl = temp | PCC2_COVF | PCC2_COC | PCC2_CEN; + + + /* Step 5. VBR is already set */ +// No need to change the VBR if we are not Compare Feature of the PCC2 Timer + + /* Step 6. set the pcc timer 1 interrupt level */ +// temp = pccchip2->irqlvl1; +// temp = temp & 0xfffffff8; +// pccchip2->irqlvl1 = temp | TIMER_INT_LEVEL; + + + // KnIntrEntry clockConf; + + //clockConf.name = VME_CHIP2_TIMER1; + //clockConf.hdl = getHdlFromCf(); + //clockConf.on = clockStart_p; + //clockConf.off = clockStop_p; + //clockConf.down = clockDown_p; + //clockConf.ison = clockTest_p; + + //svIntrConnect (&clockConf); +} diff --git a/TAO/performance-tests/Cubit/COOL/MT_Cubit/pccTimer.h b/TAO/performance-tests/Cubit/COOL/MT_Cubit/pccTimer.h new file mode 100644 index 00000000000..453977e6661 --- /dev/null +++ b/TAO/performance-tests/Cubit/COOL/MT_Cubit/pccTimer.h @@ -0,0 +1,56 @@ +// $Id$ +/* + **************************************************************** + * + * Component = PCC2 Timer Header File + * + * Synopsis = + * + * + **************************************************************** + * + * + **************************************************************** + */ + + + +#ifndef _PCCTIMER_H +#define _PCCTIMER_H + +int +pccTimer(int option, int* uTime); +unsigned int +pccTime1Get(); +unsigned int +pccTimer1Reset(); +void +pccTimer1Start(); +void +pccTimer1Stop(); +unsigned int +pccTime2Get(); +unsigned int +pccTimer2Reset(); +void +pccTimer2Start(); +void +pccTimer2Stop(); +void +pccTimerInit(); + + +#define PCC2_TIMER1_START 0x0 +#define PCC2_TIMER1_STOP 0x1 +#define PCC2_TIMER1_BPOINT 0x2 +#define PCC2_TIMER2_START 0x10 +#define PCC2_TIMER2_STOP 0x20 +#define PCC2_TIMER2_BPOINT 0x40 +#define PCC2_USERDATA 0x100 + +#include <c_defs.h> +#include <mem/chAddr_f.h> + +//extern_C int sysBench __((int, int*)); + +#endif /* _PCCTIMER_H */ diff --git a/TAO/performance-tests/Cubit/COOL/MT_Cubit/server.cpp b/TAO/performance-tests/Cubit/COOL/MT_Cubit/server.cpp new file mode 100644 index 00000000000..e19d39e7bad --- /dev/null +++ b/TAO/performance-tests/Cubit/COOL/MT_Cubit/server.cpp @@ -0,0 +1,160 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// TAO/tests +// +// = FILENAME +// server.cpp +// +// = AUTHOR +// Andy Gokhale, Sumedh Mungee, and Sergio Flores-Gaitan +// +// ============================================================================ + +#include <api/binding.H> +#include <api/api.H> +#include <api/coolThreadPool.H> +#include <corba/eoa.H> +#include <corba/eorb.H> + +#include "cubit.H" +#include "cubit_impl.h" // server header file +#include "sk_cubit.H" +#include "sk_cubit.C" +#include "ace/OS.h" + +ACE_RCSID(MT_Cubit, server, "$Id$") + +CORBA_BOA_ptr boa; + +int +create_servant (void *arg) +{ + char ** argv = (char **) arg; + + CORBA_Environment env; + Cubit_ptr cubit; + Cubit_Impl cubit_impl; + + COOL_ThreadPool* MyPool_1; + u_int concurrencyModel = 0; + + if (strcmp (argv[1], "tpool") == 0) + { + // + // Defines a policy for using a pool of 20 threads. + // + concurrencyModel = THREAD_POOL; + ACE_DEBUG ((LM_DEBUG, "Using Thread Pool concurrency model\n")); + } + else if (strcmp (argv[1], "tpr") == 0) + { + // Defines policy to create a thread for each incoming + // request. + concurrencyModel = THREAD_PER_REQUEST; + ACE_DEBUG ((LM_DEBUG, "Using Thread Per Request concurrency model\n")); + } + else + { + ACE_ERROR ((LM_ERROR, "Concurrency model determination failed.\n")); + return -1; + } + + COOL_ThreadPoolControl poolCtl_1 (concurrencyModel, 1, 20, -1); + COOL_QueueControl qCtl; + + // Defines thread attributes for threads belonging to pools. + COOL_ThreadAttributes poolAttr; + struct sched_param sp; + poolAttr.init(); + poolAttr.stack_size(8192*2); + sp.sched_priority = 43; + poolAttr.sched_attr(&sp); + // + // Allocate and initialize first pool + // + MyPool_1 = new COOL_ThreadPool; + MyPool_1->init_pool(poolCtl_1, poolAttr, qCtl); + + COOL::EOABindingData bindingData (argv[2]); + bindingData.threadpool(MyPool_1); + + COOL_bind (cubit_impl, cubit, bindingData, env); + + if (env.exception ()) + { + ACE_DEBUG ((LM_ERROR, "Bind failed.\n")); + return -1; + } + + if (env.exception ()) { + ACE_DEBUG ((LM_ERROR, "Object Reference Export Failed.\n")); + return -1; + } + + ACE_DEBUG ((LM_DEBUG, "Entering boa->run ().\n")); + boa->run (); + return 0; +} + + +int +main (int argc, char** argv) +{ + CORBA_Environment env; + int i = 0; + + COOL::EOA::bind(argv[2], env); + if (env.exception()) { + ACE_DEBUG ((LM_ERROR, "Impossible to bind the ORB to the description: %s\n", argv[2])); + return -1; + } + + CORBA_ORB_ptr orb = CORBA_ORB_init (argc, argv, 0, env); + if (env.exception ()) { + 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; + } + + boa = orb->OA_init (argc, argv, 0, env); + if (env.exception ()) + { + ACE_DEBUG ((LM_ERROR, "OA_init failed..\n")); + return -1; + } + + COOL_Activity_ptr new_activity [2]; + + for (i = 0; i < 1; i++) + { + if (thisCapsule->createActivity ((COOL_ActivityFunc) create_servant, + (void *) argv, + new_activity [i]) != C_OK) + { + ACE_ERROR ((LM_ERROR, "%p\n", "activate failed\n")); + } + } + + CORBA_Long status; + for (i = 0; i < 1; i++) + { + if (new_activity [i]->join (status) != C_OK) + { + ACE_ERROR ((LM_ERROR, "%p\n", "join failed\n")); + } + } + + ACE_DEBUG ((LM_DEBUG, "Cubit server is exiting\n")); + return 0; +} diff --git a/TAO/performance-tests/Cubit/COOL/Makefile b/TAO/performance-tests/Cubit/COOL/Makefile new file mode 100644 index 00000000000..b0a5e0a8a8f --- /dev/null +++ b/TAO/performance-tests/Cubit/COOL/Makefile @@ -0,0 +1,22 @@ +#---------------------------------------------------------------------------- +# $Id$ +# +# Makefile for the COOL tests +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +DIRS = MT_Cubit + +#---------------------------------------------------------------------------- +# 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.nested.GNU +include $(ACE_ROOT)/include/makeinclude/rules.nolocal.GNU + |