diff options
Diffstat (limited to 'TAO/tests/CDR/allocator.cpp')
-rw-r--r-- | TAO/tests/CDR/allocator.cpp | 254 |
1 files changed, 254 insertions, 0 deletions
diff --git a/TAO/tests/CDR/allocator.cpp b/TAO/tests/CDR/allocator.cpp new file mode 100644 index 00000000000..5f0acd3c5a5 --- /dev/null +++ b/TAO/tests/CDR/allocator.cpp @@ -0,0 +1,254 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// TAO/tests/CDR +// +// = FILENAME +// allocator.cpp +// +// = DESCRIPTION +// Compares the performance of a TSS allocator, with no locks, to +// the global allocator (with locks) even in the abscence of +// contention. +// The idea behind this test is to measure the predictability of +// each allocator, specially under the light of potential +// fragmentation in the main allocator. +// +// = AUTHORS +// Carlos O'Ryan +// +// ============================================================================ + +#include "tao/ORB_Core.h" +#include "tao/ORB.h" + +#include "ace/Get_Opt.h" +#include "ace/High_Res_Timer.h" + +ACE_RCSID(CDR, allocator, "$Id$") + +#define DEFAULT_BUFFER_SIZE 512 + +class Application_Simulator +{ + // = DESCRIPTION + // Tries to simulate the behavior of an application: it randomly + // acquires and releases memory, of variable sizes. + // The intention is to produce some level of fragmentation in main + // memory. + +public: + Application_Simulator (int max_fragments, + int max_fragment_size); + // Constructor, limits the amount of fragmentation and memory this + // class takes. + + ~Application_Simulator (void); + // Destructor, releases any memory left behind. + + void upcall (ACE_RANDR_TYPE& seed); + // Simulate an upcall. The class allocates some memory and then + // releases some memory too, the amount of memory allocated and the + // number of allocations is random. + +private: + char** buffers_; + // The allocated buffers. + + int max_fragments_; + // The size of the <buffers_> array. + + int max_fragment_size_; + // The maximum size of any element of <buffers_> +}; + +int +main (int argc, char *argv[]) +{ + CORBA::ORB_var orb = + CORBA::ORB_init (argc, argv); + + int tss = 0; + int iterations = 500; + int repeat = 100; + int max_fragments = 2048; + int max_fragment_size = 1024; + int max_arguments = 16; + int max_argument_size = 1024; + int quiet = 0; + ACE_RANDR_TYPE seed = time(0); + + ACE_Get_Opt get_opt (argc, argv, "tn:f:m:s:a:b:r:q"); + int opt; + + while ((opt = get_opt ()) != EOF) + { + switch (opt) + { + case 't': + tss = 1; + break; + case 'n': + iterations = ACE_OS::atoi (get_opt.opt_arg ()); + break; + case 'r': + repeat = ACE_OS::atoi (get_opt.opt_arg ()); + break; + case 'f': + max_fragments = ACE_OS::atoi (get_opt.opt_arg ()); + break; + case 'm': + max_fragment_size = ACE_OS::atoi (get_opt.opt_arg ()); + break; + case 's': + seed = ACE_OS::atoi (get_opt.opt_arg ()); + break; + case 'a': + max_arguments = ACE_OS::atoi (get_opt.opt_arg ()); + break; + case 'b': + max_argument_size = ACE_OS::atoi (get_opt.opt_arg ()); + break; + case 'q': + quiet = 1; + break; + case '?': + default: + ACE_DEBUG ((LM_DEBUG, + "Usage: %s " + "-n iterations " + "-n repeat " + "-f max_fragments " + "-m max_fragment_size " + "-s seed " + "-a max_arguments " + "-b max_argument_size " + "\n", + argv[0])); + return -1; + } + } + + ACE_DEBUG ((LM_DEBUG, "SEED = %d\n", seed)); + + ACE_Allocator* buffer_allocator = + ACE_Allocator::instance (); + ACE_Allocator* dblock_allocator = + ACE_Allocator::instance (); + if (tss) + { + buffer_allocator = + TAO_ORB_Core_instance ()->output_cdr_buffer_allocator (); + dblock_allocator = + TAO_ORB_Core_instance ()->output_cdr_dblock_allocator (); + } + + Application_Simulator simulator (max_fragments, + max_fragment_size); + char* argument_buffer; + ACE_NEW_RETURN (argument_buffer, char[max_argument_size], 1); + + int* argument_sizes; + ACE_NEW_RETURN (argument_sizes, int[max_arguments], 1); + + int n = ACE_OS::rand_r (seed) % max_arguments + 1; + for (int k = 0; k < n; ++k) + argument_sizes[k] = ACE_OS::rand_r (seed) % max_argument_size + 1; + + for (int i = 0; i < iterations; ++i) + { + simulator.upcall (seed); + + // @@ TODO this is the place to put the other allocators. + ACE_High_Res_Timer cdr_encoding; + for (int j = 0; j < repeat; ++j) + { + cdr_encoding.start_incr (); + + char buffer[DEFAULT_BUFFER_SIZE]; + ACE_OutputCDR cdr (buffer, sizeof(buffer), + TAO_ENCAP_BYTE_ORDER, + buffer_allocator, + dblock_allocator); + + for (int k = 0; k < n; ++k) + { + cdr.write_char_array (argument_buffer, + argument_sizes[k]); + } + + cdr_encoding.stop_incr (); + } + + ACE_Time_Value tv; + cdr_encoding.elapsed_time_incr (tv); + ACE_hrtime_t usecs = tv.sec (); + usecs *= static_cast<ACE_UINT32> (ACE_ONE_SECOND_IN_USECS); + usecs += tv.usec (); + double average = + static_cast<double> (ACE_HRTIME_CONVERSION(usecs)) / repeat; + + if (!quiet) + ACE_OS::printf ("AVE: %d %f\n", + i, average); + + } + return 0; +} + +Application_Simulator::Application_Simulator (int max_fragments, + int max_fragment_size) + : max_fragments_ (max_fragments), + max_fragment_size_ (max_fragment_size) +{ + ACE_NEW (buffers_, char*[this->max_fragments_]); + for (char** i = this->buffers_; + i != this->buffers_ + this->max_fragments_; + ++i) + *i = 0; +} + +Application_Simulator::~Application_Simulator (void) +{ + for (char** i = this->buffers_; + i != this->buffers_ + this->max_fragments_; + ++i) + { + if (*i != 0) + { + delete[] *i; + *i = 0; + } + } + delete[] this->buffers_; + this->buffers_ = 0; +} + +void +Application_Simulator::upcall (ACE_RANDR_TYPE& seed) +{ + for (char** i = this->buffers_; + i != this->buffers_ + this->max_fragments_; + ++i) + { + if (*i != 0) + { + if (ACE_OS::rand_r (seed) % 10000 < 5000) + { + delete[] *i; + *i = 0; + } + } + else + { + if (ACE_OS::rand_r (seed) % 10000 < 5000) + { + int size = ACE_OS::rand_r (seed) % + this->max_fragment_size_ + 1; + ACE_NEW (*i, char[size]); + } + } + } +} |