From 0773de98e3166ea82f16369a9b8871b1a988ab42 Mon Sep 17 00:00:00 2001 From: storri Date: Tue, 18 Mar 2003 18:57:42 +0000 Subject: Adding Metrics Cache template code --- ace/Metrics_Cache_T.cpp | 252 ++++++++++++++++++++++++++++++++++++++++++++ ace/Metrics_Cache_T.h | 225 +++++++++++++++++++++++++++++++++++++++ ace/Metrics_Cache_T.i | 274 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 751 insertions(+) create mode 100644 ace/Metrics_Cache_T.cpp create mode 100644 ace/Metrics_Cache_T.h create mode 100644 ace/Metrics_Cache_T.i diff --git a/ace/Metrics_Cache_T.cpp b/ace/Metrics_Cache_T.cpp new file mode 100644 index 00000000000..4fa64430a58 --- /dev/null +++ b/ace/Metrics_Cache_T.cpp @@ -0,0 +1,252 @@ +// $Id$ + +#ifndef METRICS_CACHE_CPP +#define METRICS_CACHE_CPP + +#define ACE_BUILD_DLL + +#if defined (ACE_ENABLE_TIMEPROBES) + #if !defined (ACE_COMPILE_TIMEPROBES) + #define ACE_COMPILE_TIMEPROBES + #endif /* ACE_COMPILE_TIMEPROBES */ +#endif /* ACE_ENABLE_TIMEPROBES */ + +#if defined (ACE_COMPILE_TIMEPROBES) + +#include "ace/Metrics_Cache.h" +#include "ace/Metrics_Cache_T.h" + +// Const strings for timeprobe event type descriptions. + +static const char * event_description_strings [] = +{ + "start", + "stop", + "suspend", + "resume" +}; + + +///////////////////////////////// +// class ACE_Metrics_Timeprobe // +///////////////////////////////// + +template +ACE_Metrics_Timeprobe::ACE_Metrics_Timeprobe (u_int id, + const char *name, + u_long size) + : + ACE_Timeprobe (size), + id_ (id), + name_ (0) +{ + if (name == 0) + { + name = ""; + } + + char * name_tmp; + ACE_NEW_MALLOC_ARRAY (name_tmp, + (char *) this->allocator ()->malloc (strlen(name)+1), + char, + strlen(name)+1); + ACE_OS::memcpy (name_tmp, name, strlen (name)+1); + name_ = name_tmp; + + this->event_descriptions (event_description_strings, + sizeof(event_description_strings)/sizeof(const char *)); +} + +template +ACE_Metrics_Timeprobe:: +ACE_Metrics_Timeprobe (ALLOCATOR *alloc, + u_int id, + const char *name, + u_long size) + : + ACE_Timeprobe (size), + id_ (id), + name_ (0) +{ + if (name == 0) + { + name = ""; + } + + char * name_tmp; + ACE_NEW_MALLOC_ARRAY (name_tmp, + (char *) this->allocator ()->malloc (strlen(name)+1), + char, + strlen(name)+1); + ACE_OS::memcpy (name_tmp, name, strlen (name)+1); + name_ = name_tmp; + + this->event_descriptions (event_description_strings, + sizeof(event_description_strings)/sizeof(const char *)); +} + +template +ACE_Metrics_Timeprobe::~ACE_Metrics_Timeprobe () +{ + if (name_) + { + this->allocator ()->free ((void*) name_); + } +} + + +// Returns true if a timeprobe matches the passed id. + +template +int +ACE_Metrics_Timeprobe::is_event (const ACE_Metrics_Timeprobe:: + ACE_METRICS_TIMEPROBE_DATA_TYPE &t, + ACE_Metrics_Timeprobe:: + event_id id) +{ + return (t.event_.event_number_ == (u_long) id) ? 1 : 0; +} + +template +const char * +ACE_Metrics_Timeprobe::probe_name (void) +{ + return name_; +} + +template +void +ACE_Metrics_Timeprobe::probe_name (char * name) +{ + char * name_tmp; + ACE_NEW_MALLOC_ARRAY (name_tmp, + (char *) this->allocator ()->malloc (strlen(name)+1), + char, + strlen(name)+1); + ACE_OS::memcpy (name_tmp, name, strlen (name)+1); + + if (name_) + { + this->allocator ()->free (name_); + } + + name_ = name_tmp; +} + +template +u_int +ACE_Metrics_Timeprobe::probe_id (void) +{ + return id_; +} + + +template +void +ACE_Metrics_Timeprobe::probe_id (u_int id) +{ + id_ = id; +} + + +// Flush the ACE metrics timeprobe into shared memory. + +template void +ACE_Metrics_Timeprobe:: +flush_ACE_Metrics_Timeprobe () +{ +#if defined (VXWORKS) + // TBD - implement this +#endif +} + + +///////////////////////////// +// Class ACE_Metrics_Cache // +///////////////////////////// + + +// Constructor. + +template +ACE_Metrics_Cache:: +ACE_Metrics_Cache (u_long table_size, + u_long number_of_probes, + ALLOCATOR *alloc) + : probe_set_size_ (0), + enqueue_names_ (0), + dequeue_names_ (0), + consumer_index_ (0), + supplier_index_ (1), + table_size_ (table_size), + interval_start_ (ACE_Time_Value::zero), + interval_end_ (ACE_Time_Value::zero), + interval_initialized_ (0), + metrics_enabled_(1), + allocator_ (alloc) +{ + ACE_UNUSED_ARG(number_of_probes); + // Initialize probe and count arrays. + + // Ensure that the high res timer global scale factor + // is set before any of its static methods are used + ACE_High_Res_Timer::global_scale_factor (); + + enqueue_count_ [0] = 0; + enqueue_count_ [1] = 0; + dequeue_count_ [0] = 0; + dequeue_count_ [1] = 0; + enqueue_probes_ [0] = 0; + enqueue_probes_ [1] = 0; + dequeue_probes_ [0] = 0; + dequeue_probes_ [1] = 0; +} + +// Destructor. + +template +ACE_Metrics_Cache::~ACE_Metrics_Cache () +{ +} + + +// Obtain an allocator pointer correctly thunked for the current +// address space. If there is no allocator stored in the instance, +// the singleton allocator in the current process is used. + +template ALLOCATOR * +ACE_Metrics_Cache::allocator (void) +{ + ALLOCATOR * alloc = allocator_; + return alloc + ? alloc + : ACE_Singleton::instance (); +} + + +// Flush the ACE metrics cache into shared memory. + +template void +ACE_Metrics_Cache:: +flush_ACE_Metrics_Cache () +{ +#if defined (VXWORKS) + // TBD - implement this +#endif +} + + +#if !defined (__ACE_INLINE__) +#include "ace/Metrics_Cache_T.i" +#endif /* __ACE_INLINE__ */ + +#endif /* defined (ACE_COMPILE_TIMEPROBES) */ + +#endif /* METRICS_CACHE_CPP */ + + + + + diff --git a/ace/Metrics_Cache_T.h b/ace/Metrics_Cache_T.h new file mode 100644 index 00000000000..02dd264a834 --- /dev/null +++ b/ace/Metrics_Cache_T.h @@ -0,0 +1,225 @@ +// $Id$ + +#ifndef METRICS_CACHE_T_H +#define METRICS_CACHE_T_H + +#include "ace/OS.h" + +// helpful macro definitions +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if defined (ACE_COMPILE_TIMEPROBES) + +#include "ace/Timeprobe.h" +#include "ace/Timeprobe_T.h" + +// Defaults for initializing timeprobes and timeprobe arays. +#define METRICS_MIN_TIMEPROBE_TABLE_SIZE 256 * 4 +#define METRICS_MAX_TIMEPROBE_TABLE_SIZE 256 * 256 +#define METRICS_DEFAULT_TIMEPROBE_TABLE_SIZE METRICS_MIN_TIMEPROBE_TABLE_SIZE +#define METRICS_DEFAULT_TIMEPROBE_COUNT 6 + +template +class ACE_Metrics_Timeprobe : + public ACE_Timeprobe + { + // = TITLE + // This class implements a timeprobe for use in a Metrics framework. + // + // = DESCRIPTION + // This class provides a probe for specific thread and method call + // metrics timing points. +public: + + typedef ACE_Metrics_Timeprobe + ACE_METRICS_TIMEPROBE_TYPE; + + typedef ACE_timeprobe_t ACE_METRICS_TIMEPROBE_DATA_TYPE; + typedef ACE_METRICS_TIMEPROBE_TYPE* ACE_METRICS_TIMEPROBE_BASED_PTR_TYPE; + typedef char* ACE_METRICS_NAME_BASED_PTR_TYPE; + + enum event_id + { + WORK_START = 0, + WORK_STOP = 1, + WORK_SUSPEND = 2, + WORK_RESUME = 3 + }; + // Enumerated timeprobe event types. + + ACE_Metrics_Timeprobe (u_int id = 0, + const char *name = 0, + u_long size = METRICS_DEFAULT_TIMEPROBE_TABLE_SIZE); + // Default constructor: plugs in the above event descriptions. + + ACE_Metrics_Timeprobe (ALLOCATOR *allocatorPtr, + u_int id = 0, + const char *name = 0, + u_long size = METRICS_DEFAULT_TIMEPROBE_TABLE_SIZE); + // Constructor with allocator: plugs in the above event descriptions. + + ~ACE_Metrics_Timeprobe (); + // Destructor. + + int is_event (const ACE_METRICS_TIMEPROBE_DATA_TYPE &t, + ACE_Metrics_Timeprobe::event_id id); + // Returns true if a timeprobe event matches the passed id. + + const char * probe_name (void); + void probe_name (char * name); + // Accessor and mutator for probe name. + + u_int probe_id (void); + // Accessor for probe id. + + void probe_id (u_int id); + // Mutator for probe id. + + void flush_ACE_Metrics_Timeprobe (); + // Flush the ACE metrics timeprobe into shared memory. + +protected: + + u_int id_; + // Identifier for the timeprobe. + + char* name_; + // Name of the timeprobe. + +private: + + // Declare but do not define. + ACE_Metrics_Timeprobe (const ACE_Metrics_Timeprobe &); + void operator =(const ACE_Metrics_Timeprobe &); +}; + + +template +class ACE_Metrics_Cache +{ + // = TITLE + // This class implements a cache for metrics timeprobe data. + // + // = DESCRIPTION + // This class allows probes to be recorded into a single cache that + // monitors and other higher level metrics classes can query. +public: + + typedef ACE_Metrics_Cache ACE_METRICS_CACHE_TYPE; + + ACE_Metrics_Cache (u_long table_size + = METRICS_DEFAULT_TIMEPROBE_TABLE_SIZE, + u_long number_of_probes + = METRICS_DEFAULT_TIMEPROBE_COUNT, + ALLOCATOR * allocatorPtr = 0); + // Default constructor. + + ~ACE_Metrics_Cache (); + // Destructor. + + // = Dispatching metrics. + + void report_enqueue_start (u_int i); + void report_enqueue_stop (u_int i); + void report_enqueue_suspend (u_int i); + void report_enqueue_resume (u_int i); + // Report start, stop, suspend, and resume times of a dispatch + // enqueue: stores data metrics on the supplier side. + + void report_dequeue_start (u_int i); + void report_dequeue_stop (u_int i); + void report_dequeue_suspend (u_int i); + void report_dequeue_resume (u_int i); + // Report start, stop, suspend, and resume times of a dispatch + // dequeue: stores data metrics on the supplier side.. + + void reset_base_statistics (); + // Reset the metrics data on the consumer side. + + void flip_supplier_and_consumer (); + // Flips the supplier and consumer sides. + + void flush_ACE_Metrics_Cache (); + // Flush the ACE metrics cache into shared memory. + + void metrics_enabled(int enabled); + // Set the enable state for metrics collection. + + int metrics_enabled(void) const; + // Return the enable state for metrics collection. + +protected: + + ALLOCATOR * allocator (void); + // Obtain an allocator pointer correctly thunked for the current + // address space. If there is no allocator stored in the instance, + // the singleton allocator in the current process is used. + + // = Implementation members. + + u_long probe_set_size_; + // Number of probes in each supplier/consumer set. + + u_long * enqueue_count_ [2]; + u_long * dequeue_count_ [2]; + // Probe data counts for each supplier/consumer set. + + ACE_Metrics_Timeprobe ** enqueue_probes_ [2]; + ACE_Metrics_Timeprobe ** dequeue_probes_ [2]; + // Probes for each supplier/consumer set. + + char ** enqueue_names_; + char ** dequeue_names_; + // Names for the probes. + + int consumer_index_; + // Index from which probe events are being consumed. + // for WSOA, it's the data being sent to the logger + + int supplier_index_; + // Index to which probe events are being supplied. + // for WSOA, it's the data being recorded from the probes + + u_long table_size_; + // Size of the timestamp table in each probe. + + ACE_Time_Value interval_start_; + // Interval start and stop timestamps. + + ACE_Time_Value interval_end_; + // Interval start and stop timestamps. + + int interval_initialized_; + // Flag to indicate whether or not start time of interval has been + // initialized since the last reset. + + int metrics_enabled_; + // Indicator of whether metrics is enabled. + +private: + + ALLOCATOR* allocator_; + // Allocation strategy object. + + // Declare but do not define. + ACE_Metrics_Cache (const ACE_Metrics_Cache &); + void operator = (const ACE_Metrics_Cache &); +}; + +#if defined (__ACE_INLINE__) +#include "Metrics_Cache_T.i" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Metrics_Cache_T.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Metrics_Cache_T.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#endif /* defined (ACE_COMPILE_TIMEPROBES) */ + +#endif /* METRICS_CACHE_T_H */ diff --git a/ace/Metrics_Cache_T.i b/ace/Metrics_Cache_T.i new file mode 100644 index 00000000000..f1952d93419 --- /dev/null +++ b/ace/Metrics_Cache_T.i @@ -0,0 +1,274 @@ +// $Id$ + +#ifndef METRICS_CACHE_T_I +#define METRICS_CACHE_T_I + +///////////////////////////// +// Class ACE_Metrics_Cache // +///////////////////////////// + + +template +ACE_INLINE void +ACE_Metrics_Cache::report_enqueue_start (u_int i) +{ + if (i < this->probe_set_size_) + { + u_long & count = +// Modified by BRM. This should work for ACE_Based_Pointers as well. +// this->enqueue_count_ [this->supplier_index_].addr() [i]; + this->enqueue_count_ [this->supplier_index_] [i]; + ++count; + + if (! this->interval_initialized_) + { + this->interval_initialized_ = 1; + ACE_hrtime_t hrtime_now = ACE_OS::gethrtime (); + ACE_High_Res_Timer::hrtime_to_tv (this->interval_start_, + hrtime_now); + this->interval_end_.set (this->interval_start_.sec(), + this->interval_start_.usec()); + } + + // Take the metrics timeprobe last, to avoid measuring the above + // metrics processing. + ACE_Metrics_Timeprobe * probe = +// Modified by BRM. This should work for ACE_Based_Pointers as well. +// this->enqueue_probes_ [this->supplier_index_].addr () [i].addr (); + this->enqueue_probes_ [this->supplier_index_][i]; + probe-> + timeprobe (ACE_Metrics_Timeprobe::WORK_START); + } +} + + +template +ACE_INLINE void +ACE_Metrics_Cache::report_enqueue_stop (u_int i) +{ + if (i < this->probe_set_size_) + { + // Take the metrics timeprobe first, to avoid measuring the below + // metrics processing. + ACE_Metrics_Timeprobe * probe = +// Modified by BRM. This should work for ACE_Based_Pointers as well. +// this->enqueue_probes_ [this->supplier_index_].addr () [i].addr (); + this->enqueue_probes_ [this->supplier_index_][i]; + probe-> + timeprobe (ACE_Metrics_Timeprobe::WORK_STOP); + + ACE_hrtime_t hrtime_now = ACE_OS::gethrtime (); + ACE_High_Res_Timer::hrtime_to_tv (this->interval_end_, + hrtime_now); + +// Modified by BRM. This should work for ACE_Based_Pointers as well. +// u_long & count = enqueue_count_ [this->supplier_index_].addr() [i]; + u_long & count = enqueue_count_ [this->supplier_index_][i]; + ++count; + } + +} + + +template +ACE_INLINE void +ACE_Metrics_Cache::report_enqueue_suspend (u_int i) +{ + if (i < this->probe_set_size_) + { + ACE_Metrics_Timeprobe * probe = +// Modified by BRM. This should work for ACE_Based_Pointers as well. +// this->enqueue_probes_ [this->supplier_index_].addr () [i].addr (); + this->enqueue_probes_ [this->supplier_index_][i]; + probe-> + timeprobe (ACE_Metrics_Timeprobe::WORK_SUSPEND); + u_long & count = +// Modified by BRM. This should work for ACE_Based_Pointers as well. +// this->enqueue_count_ [this->supplier_index_].addr() [i]; + this->enqueue_count_ [this->supplier_index_] [i]; + ++count; + } +} + + +template +ACE_INLINE void +ACE_Metrics_Cache::report_enqueue_resume (u_int i) +{ + if (i < this->probe_set_size_) + { + u_long & count = +// Modified by BRM. This should work for ACE_Based_Pointers as well. +// this->enqueue_count_ [this->supplier_index_].addr() [i]; + this->enqueue_count_ [this->supplier_index_] [i]; + ++count; + ACE_Metrics_Timeprobe * probe = +// Modified by BRM. This should work for ACE_Based_Pointers as well. +// this->enqueue_probes_ [this->supplier_index_].addr () [i].addr (); + this->enqueue_probes_ [this->supplier_index_][i]; + probe-> + timeprobe (ACE_Metrics_Timeprobe::WORK_RESUME); + } +} + + +template +ACE_INLINE void +ACE_Metrics_Cache::report_dequeue_start (u_int i) +{ + if (i < this->probe_set_size_) + { + u_long & count = +// Modified by BRM. This should work for ACE_Based_Pointers as well. +// this->dequeue_count_ [this->supplier_index_].addr() [i]; + this->dequeue_count_ [this->supplier_index_] [i]; + ++count; + + if (! this->interval_initialized_) + { + this->interval_initialized_ = 1; + ACE_hrtime_t hrtime_now = ACE_OS::gethrtime (); + ACE_High_Res_Timer::hrtime_to_tv (this->interval_start_, + hrtime_now); + this->interval_end_.set (this->interval_start_.sec(), + this->interval_start_.usec()); + } + + // Take the metrics timeprobe last, to avoid measuring the above + // metrics processing. + ACE_Metrics_Timeprobe * probe = +// Modified by BRM. This should work for ACE_Based_Pointers as well. +// this->dequeue_probes_ [this->supplier_index_].addr () [i].addr (); + this->dequeue_probes_ [this->supplier_index_][i]; + probe-> + timeprobe (ACE_Metrics_Timeprobe::WORK_START); + } +} + + +template +ACE_INLINE void +ACE_Metrics_Cache::report_dequeue_stop (u_int i) +{ + if (i < this->probe_set_size_) + { + // Take the metrics timeprobe first, to avoid measuring the + // metrics processing below. + ACE_Metrics_Timeprobe * probe = +// Modified by BRM. This should work for ACE_Based_Pointers as well. +// this->dequeue_probes_ [this->supplier_index_].addr () [i].addr (); + this->dequeue_probes_ [this->supplier_index_][i]; + + probe->timeprobe (ACE_Metrics_Timeprobe::WORK_STOP); + + ACE_hrtime_t hrtime_now = ACE_OS::gethrtime (); + ACE_High_Res_Timer::hrtime_to_tv (this->interval_end_, + hrtime_now); + +// Modified by BRM. This should work for ACE_Based_Pointers as well. +// u_long & count = dequeue_count_ [this->supplier_index_].addr() [i]; + u_long & count = dequeue_count_ [this->supplier_index_] [i]; + ++count; + } +} + + +template +ACE_INLINE void +ACE_Metrics_Cache::report_dequeue_suspend (u_int i) +{ + if (i < this->probe_set_size_) + { + u_long & count = +// Modified by BRM. This should work for ACE_Based_Pointers as well. +// this->dequeue_count_ [this->supplier_index_].addr() [i]; + this->dequeue_count_ [this->supplier_index_] [i]; + ++count; + ACE_Metrics_Timeprobe * probe = +// Modified by BRM. This should work for ACE_Based_Pointers as well. +// this->dequeue_probes_ [this->supplier_index_].addr () [i].addr (); + this->dequeue_probes_ [this->supplier_index_][i]; + probe-> + timeprobe (ACE_Metrics_Timeprobe::WORK_SUSPEND); + } +} + + +template +ACE_INLINE void +ACE_Metrics_Cache::report_dequeue_resume (u_int i) +{ + if (i < this->probe_set_size_) + { + u_long & count = +// Modified by BRM. This should work for ACE_Based_Pointers as well. +// this->dequeue_count_ [this->supplier_index_].addr() [i]; + this->dequeue_count_ [this->supplier_index_] [i]; + ++count; + ACE_Metrics_Timeprobe * probe = +// Modified by BRM. This should work for ACE_Based_Pointers as well. +// this->dequeue_probes_ [this->supplier_index_].addr () [i].addr (); + this->dequeue_probes_ [this->supplier_index_][i]; + probe-> + timeprobe (ACE_Metrics_Timeprobe::WORK_RESUME); + } +} + + +template +ACE_INLINE void +ACE_Metrics_Cache::reset_base_statistics () +{ + this->interval_initialized_ = 0; + this->interval_start_.set (0, 0); + this->interval_end_.set (0, 0); + + for (u_int i = 0; i < this->probe_set_size_; ++i) + { +// Modified by BRM. This should work for ACE_Based_Pointers as well. +// this->enqueue_count_ [this->consumer_index_].addr() [i] = 0; + this->enqueue_count_ [this->consumer_index_] [i] = 0; +// Modified by BRM. This should work for ACE_Based_Pointers as well. +// this->dequeue_count_ [this->consumer_index_].addr() [i] = 0; + this->dequeue_count_ [this->consumer_index_] [i] = 0; + + ACE_Metrics_Timeprobe * probe = +// Modified by BRM. This should work for ACE_Based_Pointers as well. +// this->enqueue_probes_ [this->consumer_index_].addr () [i].addr (); + this->enqueue_probes_ [this->consumer_index_][i]; + probe->reset (); + probe = +// Modified by BRM. This should work for ACE_Based_Pointers as well. +// this->dequeue_probes_ [this->consumer_index_].addr () [i].addr (); + this->dequeue_probes_ [this->consumer_index_][i]; + probe->reset (); + } +} + + +// Flips the supplier and consumer positions. + +template +ACE_INLINE void +ACE_Metrics_Cache::flip_supplier_and_consumer () +{ + int temp = consumer_index_; + consumer_index_ = supplier_index_; + supplier_index_ = temp; +} + +template +ACE_INLINE void +ACE_Metrics_Cache::metrics_enabled(int enabled) +{ + metrics_enabled_ = enabled; +} + +template +ACE_INLINE int +ACE_Metrics_Cache::metrics_enabled(void) const +{ + return metrics_enabled_; +} + +#endif /* METRICS_CACHE_T_I */ -- cgit v1.2.1