diff options
Diffstat (limited to 'TAO/performance-tests/Cubit/TAO/MT_Cubit/Task_Client.cpp')
-rw-r--r-- | TAO/performance-tests/Cubit/TAO/MT_Cubit/Task_Client.cpp | 1168 |
1 files changed, 0 insertions, 1168 deletions
diff --git a/TAO/performance-tests/Cubit/TAO/MT_Cubit/Task_Client.cpp b/TAO/performance-tests/Cubit/TAO/MT_Cubit/Task_Client.cpp deleted file mode 100644 index 8c811be3f94..00000000000 --- a/TAO/performance-tests/Cubit/TAO/MT_Cubit/Task_Client.cpp +++ /dev/null @@ -1,1168 +0,0 @@ -// $Id$ - -#include "Task_Client.h" -#include "Timer.h" -#include "ace/Stats.h" -#include "tao/TAO_Internal.h" - -#if defined (ACE_HAS_QUANTIFY) -# include "quantify.h" -#endif /* ACE_HAS_QUANTIFY */ - -inline -ACE_UINT32 -ACE_round (ACE_timer_t t) -{ -#if defined (ACE_LACKS_FLOATING_POINT) - return t; -#else - return ACE_static_cast (ACE_UINT32, t); -#endif -} - -ACE_RCSID(MT_Cubit, Task_Client, "$Id$") - -Task_State::Task_State (void) - : barrier_ (0), - key_ ("Cubit"), - loop_count_ (1000), - thread_count_ (2), - latency_ (0), - ave_latency_ (0), - datatype_ (CB_OCTET), - thread_per_rate_ (0), - global_jitter_array_ (0), - count_ (0), - shutdown_ (0), - oneway_ (0), - one_ior_ (0), - one_to_n_test_ (0), - context_switch_test_ (0), - iors_ (0), - iors_count_ (0), - ior_file_ (0), - granularity_ (1), - use_utilization_test_ (0), - high_priority_loop_count_ (0), - semaphore_ (0), - use_multiple_priority_ (0), - ready_ (0), - ready_cnd_ (ready_mtx_), - remote_invocations_ (1), - util_test_time_ (0) -{ -} - -int -Task_State::parse_args (int argc,char *argv[]) -{ - ACE_Get_Opt opts (argc, argv, "mu:n:t:d:rxof:g:1cl"); - int c; - - while ((c = opts ()) != -1) - switch (c) { - case 'g': - granularity_ = ACE_OS::atoi (opts.optarg); - if (granularity_ < 1) - granularity_ = 1; - break; - case 'l': - remote_invocations_ = 0; - break; - case 'c': - context_switch_test_ = 1; - break; - case 'm': - use_multiple_priority_ = 1; - break; - case '1': - one_to_n_test_ = 1; - break; - case 'u': - use_utilization_test_ = 1; - loop_count_ = ACE_OS::atoi (opts.optarg); - break; - case 'f': - ior_file_ = ACE_OS::strdup (opts.optarg); - break; - case 'o': - oneway_ = 1; - break; - case 'x': - shutdown_ = 1; - break; - case 'r': - thread_per_rate_ = 1; - break; - case 'd': - { - int 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 '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 '?': - default: - ACE_DEBUG ((LM_DEBUG, "usage: %s\t" - "[<ORB OPTIONS>] // ORB options, e.g., \"-ORBobjrefstyle url\" \n\t\t\t" - "[-d <datatype>] // what datatype to use for calls: Octet=0, Short=1, Long=2, Struct=3 \n\t\t\t" - "[-n <num_calls>] // number of CORBA calls to make. \n\t\t\t" - "[-t <num_of_clients>] // number of client threads to create \n\t\t\t" - "[-f <ior_file>] // specify the file from which we read the object references (iors), if any.\n\t\t\t" - "[-r] // run thread-per-rate test. \n\t\t\t" - "[-o] // makes client use oneway calls. By default, twoway calls are used. \n\t\t\t" - "[-x] // makes a call to servant to shutdown \n\t\t\t" - "[-u <requests> ] // run the client utilization test for a number of <requests> \n\t\t\t" - "[-1] // run the one-to-n test. \n\t\t\t" - "[-g <granularity>] // choose the granularity of the timing of CORBA calls \n\t\t\t" - "[-c] // run the number of context switches test. \n\t\t\t" - "[-l] // use direct function calls, as opposed to CORBA requests. ONLY to be used with -u option.\n\t\t\t" - "[-m] // use multiple priorities for the low priority clients. \n" - ,argv [0])); - return -1; - } - - if (thread_per_rate_ == 1) - thread_count_ = THREAD_PER_RATE_OBJS; - - if (use_utilization_test_ == 1) - { - thread_count_ = 1; - shutdown_ = 1; - datatype_ = CB_OCTET; - } - - // Allocate the array of character pointers. - ACE_NEW_RETURN (iors_, - char *[thread_count_], - -1); - - if (ior_file_ != 0) - { - FILE *ior_file = - ACE_OS::fopen (ior_file_, "r"); - - if (ior_file == 0) - ACE_ERROR_RETURN ((LM_ERROR, - "Task_State::parse_args; " - "unable to open IOR file \"%s\"\n", - ior_file_), - -1); - char buf[BUFSIZ]; - u_int i; - - for (i = 0; - ACE_OS::fgets (buf, BUFSIZ, ior_file) != 0 - && i < thread_count_; - i++) - { - ACE_DEBUG ((LM_DEBUG, - buf)); - int j = ACE_OS::strlen (buf); - - // This overwrites the '\n' that was read from the file. - buf[j - 1] = 0; - iors_[i] = ACE_OS::strdup (buf); - } - - this->iors_count_ = i; - ACE_OS::fclose (ior_file); - } - - // thread_count_ + 2 because there is one utilization thread also - // wanting to begin at the same time the clients begin && the main - // thread wants to know when clients will start running to get - // accurate context switch numbers. - - if (thread_per_rate_ == 0) - { - if (use_utilization_test_ == 1) - // If we are to use the utilization test, include it in the - // barrier count. See description of this variable in header - // file. - ACE_NEW_RETURN (barrier_, - ACE_Barrier (thread_count_ + 2), - -1); - else - ACE_NEW_RETURN (barrier_, - ACE_Barrier (thread_count_ + 1), - -1); - } - else - ACE_NEW_RETURN (this->barrier_, - ACE_Barrier (thread_count_), - -1); - ACE_NEW_RETURN (this->semaphore_, - ACE_Thread_Semaphore (0), - -1); - ACE_NEW_RETURN (this->latency_, - ACE_timer_t [thread_count_], - -1); - ACE_NEW_RETURN (this->global_jitter_array_, - JITTER_ARRAY *[this->thread_count_], - -1); - ACE_NEW_RETURN (this->count_, - u_int [thread_count_], - -1); - return 0; -} - -Task_State::~Task_State (void) -{ - int i; - - if (this->ior_file_ != 0) - ACE_OS::free (this->ior_file_); - - // Delete the strduped memory. - for (i = 0; i < this->iors_count_; i++) - ACE_OS::free (this->iors_ [i]); - - delete [] this->iors_; - // Delete the barrier. - - delete this->barrier_; - delete this->semaphore_; - delete [] this->latency_; - delete [] this->ave_latency_; - delete [] this->global_jitter_array_; - delete [] this->count_; -} - -Client::Client (ACE_Thread_Manager *thread_manager, - Task_State *ts, - int argc, - char **argv, - u_int id) - : ACE_Task<ACE_SYNCH> (thread_manager), - cubit_impl_ (0), - ts_ (ts), - num_ (0), - id_ (id), - call_count_ (0), - error_count_ (0), - my_jitter_array_ (0), - timer_ (0), - frequency_ (0), - orb_ (0), - latency_ (0), - argc_ (argc), - argv_ (argv) -{ -} - -Client::~Client (void) -{ - delete this->my_jitter_array_; - delete this->timer_; -} - -ACE_INLINE int -Client::func (u_int i) -{ - return i - 117; -} - -void -Client::put_latency (JITTER_ARRAY *jitter, - ACE_timer_t latency, - u_int thread_id, - u_int count) -{ - ACE_MT (ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->ts_->lock_)); - - this->ts_->latency_[thread_id] = latency; - this->ts_->global_jitter_array_[thread_id] = jitter; - this->ts_->count_[thread_id] = count; - - ACE_DEBUG ((LM_DEBUG, - "(%t) My latency was %A msec\n", - latency/ACE_ONE_SECOND_IN_MSECS)); -} - -// Returns the latency in usecs. -ACE_timer_t -Client::get_high_priority_latency (void) -{ - return (ACE_timer_t) this->ts_->latency_ [0]; -} - -// Returns the latency in usecs. -ACE_timer_t -Client::get_low_priority_latency (void) -{ - if (this->ts_->thread_count_ == 1) - return 0; - - ACE_timer_t l = 0; - - for (u_int i = 1; - i < this->ts_->thread_count_; - i++) - l += (ACE_timer_t) this->ts_->latency_[i]; - - // Return the average latency for the low priority threads. - return l / (ACE_timer_t) (this->ts_->thread_count_ - 1); -} - -ACE_timer_t -Client::get_latency (u_int thread_id) -{ - return ACE_static_cast (ACE_timer_t, - this->ts_->latency_ [thread_id]); -} - -// Returns the jitter in usecs. -ACE_timer_t -Client::get_high_priority_jitter (void) -{ - ACE_timer_t jitter = 0.0; - ACE_timer_t average = get_high_priority_latency (); - u_int number_of_samples = 0; - - // Compute the standard deviation, i.e., jitter, from the values - // stored in the global_jitter_array_. - - ACE_Stats stats; - - // We first compute the sum of the squares of the differences each - // latency has from the average. - - JITTER_ARRAY_ITERATOR iterator = - this->ts_->global_jitter_array_[0]->begin (); - - // latency in usecs. - ACE_timer_t *latency = 0; - - for (iterator.first (); - iterator.next (latency) == 1; - iterator.advance ()) - { - ++number_of_samples; - - ACE_timer_t difference = *latency - average; - jitter += difference * difference; - - if (stats.sample (ACE_round (*latency)) == -1) - ACE_DEBUG ((LM_DEBUG, "Error: stats.sample returned -1\n")); - - } - - // Return the square root of the sum of the differences computed - // above, i.e., jitter. - - ACE_DEBUG ((LM_DEBUG, - "high priority jitter (%u samples):\n", number_of_samples)); - - ACE_DEBUG ((LM_DEBUG,"Latency stats (time in usec)\n")); - stats.print_summary (1, 1, stderr); - - return sqrt (jitter / (number_of_samples - 1)); -} - -// Returns the jitter in usecs. - -ACE_timer_t -Client::get_low_priority_jitter (void) -{ - if (this->ts_->thread_count_ == 1) - return 0; - - ACE_timer_t jitter = 0.0; - ACE_timer_t average = get_low_priority_latency (); - u_int number_of_samples = 0; - - // Compute the standard deviation, i.e., jitter, from the values - // stored in the global_jitter_array_. - - ACE_Stats stats; - - // We first compute the sum of the squares of the differences each - // latency has from the average. - - for (u_int j = 1; - j < this->ts_->thread_count_; - j++) - { - ACE_DEBUG ((LM_DEBUG, "count: %u\n", ts_->count_[j])); - - JITTER_ARRAY_ITERATOR iterator = - this->ts_->global_jitter_array_ [j]->begin (); - - ACE_timer_t number_of_calls = - this->ts_->count_ [j] / this->ts_->granularity_; - - ACE_timer_t *latency = 0; - - u_int i = 0; - - for (iterator.first (); - i < number_of_calls && iterator.next (latency) == 1; - iterator.advance ()) - { - ++number_of_samples; - ACE_timer_t difference = *latency - average; - jitter += difference * difference; - stats.sample (ACE_round (*latency)); - } - } - - ACE_DEBUG ((LM_DEBUG, - "low priority jitter (%u samples):\n", number_of_samples)); - ACE_DEBUG ((LM_DEBUG,"Latency stats (time in usec)\n")); - stats.print_summary (1, 1, stderr); - - // Return the square root of the sum of the differences computed - // above, i.e. jitter. - return sqrt (jitter / (number_of_samples - 1)); -} - -ACE_timer_t -Client::get_jitter (u_int id) -{ - ACE_timer_t jitter = 0.0; - ACE_timer_t average = get_latency (id); - u_int number_of_samples = 0; - - // Compute the standard deviation, i.e., jitter, from the values - // stored in the global_jitter_array_. - - ACE_Stats stats; - - // We first compute the sum of the squares of the differences each - // latency has from the average. - - JITTER_ARRAY_ITERATOR iterator = - this->ts_->global_jitter_array_ [id]->begin (); - - ACE_timer_t number_of_calls = - this->ts_->count_[id] / this->ts_->granularity_; - - ACE_timer_t *latency = 0; - - u_int i = 0; - - for (iterator.first (); - i < number_of_calls && iterator.next (latency) == 1; - i ++,iterator.advance ()) - { - ++number_of_samples; - ACE_timer_t difference = *latency - average; - jitter += difference * difference; - stats.sample (ACE_round (*latency)); - } - - ACE_DEBUG ((LM_DEBUG, - "jitter for thread id %u:\n", id)); - ACE_DEBUG ((LM_DEBUG,"Latency stats (time in usec)\n")); - stats.print_summary (1, 1, stderr); - - // Return the square root of the sum of the differences computed - // above, i.e. jitter. - return sqrt (jitter / (number_of_samples - 1)); -} - -void -Client::find_frequency (void) -{ - if (this->ts_->thread_per_rate_ == 0) - { - if (this->id_ == 0) - { - ACE_DEBUG ((LM_DEBUG, - "(%t) I'm the high priority client, my id is %d.\n", - this->id_)); - this->frequency_ = CB_HIGH_PRIORITY_RATE; - } - else - { - ACE_DEBUG ((LM_DEBUG, - "(%t) I'm a low priority client, my id is %d.\n", - this->id_)); - this->frequency_ = CB_LOW_PRIORITY_RATE; - } - } - else - switch (this->id_) - { - case CB_20HZ_CONSUMER: - this->frequency_ = CB_20HZ_CONSUMER_RATE; - ACE_DEBUG ((LM_DEBUG, - "(%t) I'm a %u Hz frequency client, " - "my id is %u.\n", - CB_20HZ_CONSUMER_RATE, - this->id_)); - break; - case CB_10HZ_CONSUMER: - this->frequency_ = CB_10HZ_CONSUMER_RATE; - ACE_DEBUG ((LM_DEBUG, - "(%t) I'm a %u Hz frequency client, " - "my id is %u.\n", - CB_10HZ_CONSUMER_RATE, - this->id_)); - break; - case CB_5HZ_CONSUMER: - this->frequency_ = CB_5HZ_CONSUMER_RATE; - ACE_DEBUG ((LM_DEBUG, - "(%t) I'm a %u Hz frequency client, " - "my id is %u.\n", - CB_5HZ_CONSUMER_RATE, - this->id_)); - break; - case CB_1HZ_CONSUMER: - this->frequency_ = CB_1HZ_CONSUMER_RATE; - ACE_DEBUG ((LM_DEBUG, - "(%t) I'm a %u Hz frequency client, " - "my id is %u.\n", - CB_1HZ_CONSUMER_RATE, - this->id_)); - break; - default: - ACE_DEBUG ((LM_DEBUG, - "(%t) Invalid Thread ID!!!!\n", - this->id_)); - } -} - -int -Client::init_orb (void) -{ - TAO_TRY - { - ACE_DEBUG ((LM_DEBUG, - "I'm thread %t\n")); - - - // Convert the argv vector into a string. - ACE_ARGV tmp_args (this->argv_); - char tmp_buf[BUFSIZ]; - - ACE_OS::strcpy (tmp_buf, - tmp_args.buf ()); - // Add the argument. - ACE_OS::strcat (tmp_buf, - " -ORBrcvsock 32768 " - " -ORBsndsock 32768 "); - - ACE_DEBUG ((LM_DEBUG, - tmp_buf)); - - // Convert back to argv vector style. - ACE_ARGV tmp_args2 (tmp_buf); - int argc = tmp_args2.argc (); - char **argv = tmp_args2.argv (); - - this->orb_ = CORBA::ORB_init (argc, - argv, - "internet", - TAO_TRY_ENV); - TAO_CHECK_ENV; - if (this->id_ == 0) - { - ACE_DEBUG ((LM_DEBUG, - "parsing the arguments\n")); - - int result = this->ts_->parse_args (argc, - argv); - if (result != 0) - return -1; - - ACE_DEBUG ((LM_DEBUG, - "(%t)Arguments parsed successfully\n")); - - ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ready_mon, this->ts_->ready_mtx_, 1)); - this->ts_->ready_ = 1; - this->ts_->ready_cnd_.broadcast (); - ready_mon.release (); - } - - ACE_DEBUG ((LM_DEBUG, - "(%t) ORB_init success\n")); - } - TAO_CATCHANY - { - TAO_TRY_ENV.print_exception ("Client::Orb_init ()"); - return -1; - } - TAO_ENDTRY; - return 0; -} - -int -Client::get_cubit (void) -{ - CORBA::Object_var objref (0); - - TAO_TRY - { - char *my_ior = - this->ts_->use_utilization_test_ == 1 - ? this->ts_->one_ior_ - : this->ts_->iors_[this->id_]; - - // If we are running the "1 to n" test make sure all low - // priority clients use only 1 low priority servant. - if (this->id_ > 0 - && this->ts_->one_to_n_test_ == 1) - my_ior = this->ts_->iors_[1]; - - if (my_ior == 0) - ACE_ERROR_RETURN ((LM_ERROR, - "Must specify valid ior filename with -f option\n"), - -1); - - objref = this->orb_->string_to_object (my_ior, - TAO_TRY_ENV); - TAO_CHECK_ENV; - - if (CORBA::is_nil (objref.in ())) - ACE_ERROR_RETURN ((LM_ERROR, - " (%t) string_to_object Failed!\n"), - -1); - - // Narrow the CORBA::Object reference to the stub object, - // checking the type along the way using _is_a. - this->cubit_ = Cubit::_narrow (objref.in (), - TAO_TRY_ENV); - TAO_CHECK_ENV; - - if (CORBA::is_nil (this->cubit_)) - ACE_ERROR_RETURN ((LM_ERROR, - "Create cubit failed\n"), - 1); - - ACE_DEBUG ((LM_DEBUG, - "(%t) Binding succeeded\n")); - - CORBA::String_var str = - this->orb_->object_to_string (this->cubit_, - TAO_TRY_ENV); - TAO_CHECK_ENV; - - ACE_DEBUG ((LM_DEBUG, - "(%t) CUBIT OBJECT connected to <%s>\n", - str.in ())); - } - TAO_CATCHANY - { - TAO_TRY_ENV.print_exception ("Client::get_cubit"); - return -1; - } - TAO_ENDTRY; - return 0; -} - -int -Client::svc (void) -{ - // Initialize the ORB. - int result = this->init_orb (); - if (result != 0) - return result; - - // Find the frequency of CORBA requests based on thread id. - this->find_frequency (); - - // Get the cubit object from the file. - result = this->get_cubit (); - if (result != 0) - return result; - - ACE_DEBUG ((LM_DEBUG, - "(%t) Waiting for other threads to " - "finish binding..\n")); - - // Wait for all the client threads to be initialized before going - // any further. - this->ts_->barrier_->wait (); - ACE_DEBUG ((LM_DEBUG, - "(%t) Everyone's done, here I go!!\n")); - if (this->ts_->oneway_ == 1) - ACE_DEBUG ((LM_DEBUG, - "(%t) **** USING ONEWAY CALLS ****\n")); - - // Perform the tests. - result = this->run_tests (); - if (result != 0) - { - ACE_ERROR ((LM_ERROR, "(%t) Error occurred in run_test ()\n")); - return result; - } - - // release the semaphore - if (this->ts_->thread_per_rate_ == 1 - && this->id_ == this->ts_->thread_count_ - 1) - this->ts_->semaphore_->release (this->ts_->thread_count_ - 1); - else - this->ts_->semaphore_->release (); - - // shutdown the server if necessary. - TAO_TRY - { - if (this->ts_->shutdown_) - { - ACE_DEBUG ((LM_DEBUG, - "(%t) CALLING SHUTDOWN() ON THE SERVANT\n")); - this->cubit_->shutdown (TAO_TRY_ENV); - TAO_CHECK_ENV; - } - } - TAO_CATCHANY - { - ACE_ERROR ((LM_ERROR, - "Shutdown of the server failed!\n")); - TAO_TRY_ENV.print_exception ("shutdown() call failed.\n"); - } - TAO_ENDTRY; - - // Delete dynamic memory - CORBA::release (this->cubit_); - - // To avoid a memPartFree on VxWorks. It will leak memory, though. - int status = 0; - - if (thr_mgr ()) - thr_mgr ()->exit (&status, 1); - else - ACE_OS::thr_exit (&status); - - return 0; -} - -int -Client::cube_octet (void) -{ - TAO_TRY - { - this->call_count_++; - // Cube an octet. - CORBA::Octet arg_octet = func (this->num_); - CORBA::Octet ret_octet = 0; - - START_QUANTIFY; - - if (this->ts_->use_utilization_test_ == 1 && this->ts_->remote_invocations_ == 0) - ret_octet = this->cubit_impl_.cube_octet (arg_octet, - TAO_TRY_ENV); - else - ret_octet = this->cubit_->cube_octet (arg_octet, - TAO_TRY_ENV); - - STOP_QUANTIFY; - TAO_CHECK_ENV; - - // Perform the cube operation. - arg_octet = arg_octet * arg_octet * arg_octet; - - if (arg_octet != ret_octet) - { - this->error_count_++; - ACE_ERROR_RETURN ((LM_ERROR, - "** cube_octet (%d) (--> %d)\n", - arg_octet, - ret_octet), - -1); - } - - } - TAO_CATCHANY - { - TAO_TRY_ENV.print_exception ("call to cube_octet()\n"); - ACE_ERROR_RETURN ((LM_ERROR, - "%s: Call failed\n", - TAO_TRY_ENV.exception ()), - -1); - } - TAO_ENDTRY; - return 0; -} - -int -Client::cube_short (void) -{ - TAO_TRY - { - this->call_count_++; - - CORBA::Short arg_short = func (this->num_); - CORBA::Short ret_short; - - START_QUANTIFY; - ret_short = this->cubit_->cube_short (arg_short, - TAO_TRY_ENV); - STOP_QUANTIFY; - TAO_CHECK_ENV; - arg_short = arg_short * arg_short * arg_short; - - if (arg_short != ret_short) - { - this->error_count_++; - ACE_ERROR_RETURN ((LM_ERROR, - "** cube_short (%d) (--> %d)\n", - arg_short , - ret_short), - -1); - } - } - TAO_CATCHANY - { - TAO_TRY_ENV.print_exception ("call to cube_short\n"); - ACE_ERROR_RETURN ((LM_ERROR, - "%s: Call failed\n", - TAO_TRY_ENV.exception ()), - -1); - } - TAO_ENDTRY; - return 0; -} - -int -Client::cube_long (void) -{ - TAO_TRY - { - this->call_count_++; - - CORBA::Long arg_long = func (this->num_); - CORBA::Long ret_long; - - START_QUANTIFY; - ret_long = this->cubit_->cube_long (arg_long, - TAO_TRY_ENV); - STOP_QUANTIFY; - TAO_CHECK_ENV; - - arg_long = arg_long * arg_long * arg_long; - - if (arg_long != ret_long) - { - this->error_count_++; - ACE_ERROR ((LM_ERROR, - "** cube_long (%d) (--> %d)\n", - arg_long, - ret_long)); - } - } - TAO_CATCHANY - { - TAO_TRY_ENV.print_exception ("call to cube_long()\n"); - ACE_ERROR_RETURN ((LM_ERROR, - "%s: Call failed\n", - TAO_TRY_ENV.exception ()), - -1); - } - TAO_ENDTRY; - return 0; -} - -int -Client::cube_struct (void) -{ - TAO_TRY - { - Cubit::Many arg_struct; - Cubit::Many ret_struct; - - this->call_count_++; - - arg_struct.l = func (this->num_); - arg_struct.s = func (this->num_); - arg_struct.o = func (this->num_); - - START_QUANTIFY; - ret_struct = this->cubit_->cube_struct (arg_struct, - TAO_TRY_ENV); - STOP_QUANTIFY; - TAO_CHECK_ENV; - - 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 ) - { - this->error_count_++; - ACE_ERROR ((LM_ERROR, - "**cube_struct error!\n")); - } - } - TAO_CATCHANY - { - TAO_TRY_ENV.print_exception - ("call to cube_struct()\n"); - ACE_ERROR_RETURN ((LM_ERROR, - "%s: Call failed\n", TAO_TRY_ENV.exception ()), - -1); - } - TAO_ENDTRY; - return 0; -} - -int -Client::make_request (void) -{ - int result; - - if (this->ts_->oneway_ == 0) - { - switch (this->ts_->datatype_) - { - case CB_OCTET: - result = this->cube_octet (); - break; - // Cube a short. - case CB_SHORT: - result = this->cube_short (); - break; - // Cube a long. - case CB_LONG: - result = this->cube_long (); - break; - // Cube a "struct" ... - case CB_STRUCT: - result = this->cube_struct (); - break; - default: - ACE_ERROR_RETURN ((LM_ERROR, - "(%P|%t); %s:%d; unexpected datatype: %d\n", - this->ts_->datatype_), -1); - } - if (result != 0) - return result; - } - else - { - TAO_TRY - { - this->call_count_++; - START_QUANTIFY; - this->cubit_->noop (TAO_TRY_ENV); - STOP_QUANTIFY; - TAO_CHECK_ENV; - } - TAO_CATCHANY - { - TAO_TRY_ENV.print_exception ("oneway call noop()\n"); - ACE_ERROR_RETURN ((LM_ERROR, - "(%t) noop() call failed\n"), - -1); - } - TAO_ENDTRY; - } - // return success. - return 0; -} - -void -Client::print_stats (void) -{ - // Perform latency stats only if we are not running the utilization - // tests. - if (this->call_count_ > 0 - && this->ts_->use_utilization_test_ == 0) - { - if (this->error_count_ == 0) - { - // Latency is in usecs. - ACE_timer_t calls_per_second = - (this->call_count_ * ACE_ONE_SECOND_IN_USECS) / this->latency_; - - // Calculate average (per-call) latency in usecs. - this->latency_ = this->latency_/this->call_count_; - - if (this->latency_ > 0) - { - ACE_DEBUG ((LM_DEBUG, - "(%P|%t) cube average call ACE_OS::time\t= %A msec, \t" - "%A calls/second\n", - this->latency_ / ACE_ONE_SECOND_IN_MSECS, - calls_per_second)); - this->put_latency (this->my_jitter_array_, - this->latency_, - this->id_, - this->call_count_); - } - else - { - // Still we have to call this function to store a valid - // array pointer. - this->put_latency (this->my_jitter_array_, - 0, - this->id_, - this->call_count_); - - ACE_DEBUG ((LM_DEBUG, - "*** Warning: Latency, %f, is less than or equal to zero." - " Precision may have been lost.\n, this->latency_")); - } - } - ACE_DEBUG ((LM_DEBUG, - "%d calls, %d errors\n", - this->call_count_, - this->error_count_)); - } -} - -ACE_timer_t -Client::calc_delta (ACE_timer_t real_time, - ACE_timer_t delta) -{ - ACE_timer_t new_delta; -#if defined (ACE_LACKS_FLOATING_POINT) - new_delta = 40 * real_time / 100 + 60 * delta / 100; -#else /* !ACE_LACKS_FLOATING_POINT */ - new_delta = 0.4 * fabs (real_time) + 0.6 * delta; -#endif /* ACE_LACKS_FLOATING_POINT */ - return new_delta; -} - -int -Client::do_test (void) -{ - ACE_timer_t delta = 0; - u_int low_priority_client_count = this->ts_->thread_count_ - 1; - ACE_timer_t sleep_time = // usec - (ACE_ONE_SECOND_IN_USECS * this->ts_->granularity_)/this->frequency_; - u_int i; - int result = 0; - - for (i = 0; - // keep running for loop count, OR - i < this->ts_->loop_count_ - // keep running if we are the highest priority thread and at - // least another lower client thread is running, OR - || (id_ == 0 && this->ts_->thread_count_ > 1) - // keep running if test is thread_per_rate and we're not the - // lowest frequency thread. - || (this->ts_->thread_per_rate_ == 1 - && id_ < (this->ts_->thread_count_ - 1)); - i++) - { - // Start timing a call. - if ((i % this->ts_->granularity_) == 0 && - this->ts_->use_utilization_test_ == 0) - { - // Delay a sufficient amount of time to be able to enforce - // the calling frequency, e.g., 20Hz, 10Hz, 5Hz, 1Hz. - ACE_Time_Value tv (0, - (u_long) (sleep_time < delta - ? 0 - : sleep_time - delta)); - ACE_OS::sleep (tv); - this->timer_->start (); - } - this->num_ = i; - // make a request to the server object depending on the datatype. - result = this->make_request (); - if (result != 0) - return 2; - - // Stop the timer. - if (i % this->ts_->granularity_ == this->ts_->granularity_ - 1 - && this->ts_->use_utilization_test_ == 0) - { - this->timer_->stop (); - - // Calculate time elapsed. - ACE_timer_t real_time; - real_time = this->timer_->get_elapsed (); - // Recalculate delta = 0.4 * elapsed_time + 0.6 * - // delta. This is used to adjust the sleeping time so that - // we make calls at the required frequency. - delta = this->calc_delta (real_time,delta); - this->latency_ += real_time * this->ts_->granularity_; - - if ((result = this->my_jitter_array_->enqueue_tail (real_time)) != 0) - ACE_DEBUG ((LM_DEBUG, "(%t) Error: my_jitter_array->enqueue_tail() returned %d\n", result)); - } - if (this->ts_->thread_per_rate_ == 1 - && id_ < (this->ts_->thread_count_ - 1)) - { - if (this->ts_->semaphore_->tryacquire () != -1) - break; - } - else - // If we are the high priority client. If tryacquire() - // succeeded then a client must have done a release () on it, - // thus we decrement the client counter. - if (id_ == 0 - && this->ts_->thread_count_ > 1) - { - if (this->ts_->semaphore_->tryacquire () != -1) - { - low_priority_client_count --; - // If all clients are done then break out of loop. - if (low_priority_client_count <= 0) - break; - } - } - - } /* end of for () */ - ACE_DEBUG ((LM_DEBUG, "(%t) do_test executed %u iterations\n", i)); - - return 0; -} - -int -Client::run_tests (void) -{ - int result; - ACE_NEW_RETURN (this->my_jitter_array_, - JITTER_ARRAY, - -1); - - ACE_NEW_RETURN (this->timer_, - MT_Cubit_Timer (this->ts_->granularity_), - -1); - if (this->ts_->use_utilization_test_ == 1) - this->timer_->start (); - - // Make the calls in a loop. - result = this->do_test (); - if (result != 0) - return result; - - if (id_ == 0) - this->ts_->high_priority_loop_count_ = - this->call_count_; - - if (this->ts_->use_utilization_test_ == 1) - { - this->timer_->stop (); - this->ts_->util_test_time_ = this->timer_->get_elapsed (); - } - - // Print the latency results. - this->print_stats (); - return 0; -} |