Timeprobe_T.cpp

Go to the documentation of this file.
00001 // Timeprobe_T.cpp,v 4.23 2006/04/19 11:54:16 jwillemsen Exp
00002 
00003 #ifndef ACE_TIMEPROBE_T_CPP
00004 #define ACE_TIMEPROBE_T_CPP
00005 
00006 #include "ace/config-all.h"
00007 
00008 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00009 # pragma once
00010 #endif /* ACE_LACKS_PRAGMA_ONCE */
00011 
00012 #if defined (ACE_COMPILE_TIMEPROBES)
00013 
00014 #include "ace/Timeprobe.h"
00015 #include "ace/High_Res_Timer.h"
00016 #include "ace/OS_NS_string.h"
00017 
00018 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00019 
00020 template <class ACE_LOCK, class ALLOCATOR>
00021 ACE_Timeprobe_Ex<ACE_LOCK, ALLOCATOR>::ACE_Timeprobe_Ex (u_long size)
00022   : timeprobes_ (0),
00023     lock_ (),
00024     max_size_ (size),
00025     current_size_ (0),
00026     report_buffer_full_ (0),
00027     allocator_ (0)
00028 {
00029   ACE_timeprobe_t *temp;
00030   ACE_NEW_MALLOC_ARRAY (temp,
00031                         (ACE_timeprobe_t *) this->allocator ()->
00032                         malloc (this->max_size_*sizeof(ACE_timeprobe_t)),
00033                         ACE_timeprobe_t,
00034                         this->max_size_);
00035   this->timeprobes_ = temp;
00036 
00037 }
00038 
00039 template <class ACE_LOCK, class ALLOCATOR>
00040 ACE_Timeprobe_Ex<ACE_LOCK, ALLOCATOR>::
00041 ACE_Timeprobe_Ex (ALLOCATOR *allocator,
00042                u_long size)
00043   : timeprobes_ (0),
00044     lock_ (),
00045     max_size_ (size),
00046     current_size_ (0),
00047     report_buffer_full_ (0),
00048     allocator_ (allocator)
00049 {
00050   ACE_timeprobe_t *temp = 0;
00051   ACE_NEW_MALLOC_ARRAY (temp,
00052                         (ACE_timeprobe_t *) this->allocator ()->
00053                         malloc (this->max_size_*sizeof(ACE_timeprobe_t)),
00054                         ACE_timeprobe_t,
00055                         this->max_size_);
00056   this->timeprobes_ = temp;
00057 
00058 }
00059 
00060 template <class ACE_LOCK, class ALLOCATOR>
00061 ACE_Timeprobe_Ex<ACE_LOCK, ALLOCATOR>::ACE_Timeprobe_Ex (const ACE_Timeprobe_Ex<ACE_LOCK, ALLOCATOR> &)
00062 {
00063   //
00064   // Stupid MSVC is forcing me to define this; please don't use it.
00065   //
00066 
00067   ACE_ERROR ((LM_ERROR,
00068               ACE_LIB_TEXT ("ACE_NOTSUP: %N, line %l\n")));
00069   errno = ENOTSUP;
00070 }
00071 
00072 template <class ACE_LOCK, class ALLOCATOR>
00073 ACE_Timeprobe_Ex<ACE_LOCK, ALLOCATOR>::~ACE_Timeprobe_Ex (void)
00074 {
00075   ACE_DES_ARRAY_FREE ((ACE_timeprobe_t *) (this->timeprobes_),
00076                       this->max_size_,
00077                       this->allocator ()->free,
00078                       ACE_timeprobe_t);
00079 }
00080 
00081 template <class ACE_LOCK, class ALLOCATOR> void
00082 ACE_Timeprobe_Ex<ACE_LOCK, ALLOCATOR>::timeprobe (u_long event)
00083 {
00084   ACE_GUARD (ACE_LOCK, ace_mon, this->lock_);
00085 
00086 # if defined (ACE_TIMEPROBE_ASSERTS_FIXED_SIZE)
00087   ACE_ASSERT (this->current_size_ < this->max_size_);
00088 # else /* ! ACE_TIMEPROBE_ASSERTS_FIXED_SIZE */
00089   // wrap around to the beginning on overflow
00090   if (this->current_size_ >= this->max_size_)
00091     {
00092       this->current_size_ = 0;
00093       this->report_buffer_full_ = 1;
00094     }
00095 # endif /* ACE_TIMEPROBE_ASSERTS_FIXED_SIZE */
00096 
00097   this->timeprobes_[this->current_size_].event_.event_number_ = event;
00098   this->timeprobes_[this->current_size_].event_type_ = ACE_timeprobe_t::NUMBER;
00099   this->timeprobes_[this->current_size_].time_ = ACE_OS::gethrtime ();
00100   this->timeprobes_[this->current_size_].thread_ = ACE_OS::thr_self ();
00101 
00102   ++this->current_size_;
00103 
00104 }
00105 
00106 template <class ACE_LOCK, class ALLOCATOR> void
00107 ACE_Timeprobe_Ex<ACE_LOCK, ALLOCATOR>::timeprobe (const char *event)
00108 {
00109   ACE_GUARD (ACE_LOCK, ace_mon, this->lock_);
00110 
00111   ACE_ASSERT (this->current_size_ < this->max_size_);
00112 
00113   this->timeprobes_[this->current_size_].event_.event_description_ = event;
00114   this->timeprobes_[this->current_size_].event_type_ = ACE_timeprobe_t::STRING;
00115   this->timeprobes_[this->current_size_].time_ = ACE_OS::gethrtime ();
00116   this->timeprobes_[this->current_size_].thread_ = ACE_OS::thr_self ();
00117 
00118   ++this->current_size_;
00119 }
00120 
00121 template <class ACE_LOCK, class ALLOCATOR> void
00122 ACE_Timeprobe_Ex<ACE_LOCK, ALLOCATOR>::reset (void)
00123 {
00124   ACE_GUARD (ACE_LOCK, ace_mon, this->lock_);
00125 
00126   this->current_size_ = 0;
00127   this->report_buffer_full_ = 0;
00128 }
00129 
00130 template <class ACE_LOCK, class ALLOCATOR> void
00131 ACE_Timeprobe_Ex<ACE_LOCK, ALLOCATOR>::increase_size (u_long size)
00132 {
00133    ACE_GUARD (ACE_LOCK, ace_mon, this->lock_);
00134 
00135    if (size > this->max_size_)
00136    {
00137       ACE_timeprobe_t *temp = 0;
00138       ACE_NEW_MALLOC_ARRAY (temp,
00139                            (ACE_timeprobe_t *) this->allocator ()->
00140                            malloc (this->max_size_
00141                            * sizeof (ACE_timeprobe_t)),
00142                            ACE_timeprobe_t,
00143                            size);
00144 
00145       if (this->max_size_ > 0)
00146       {
00147          ACE_OS::memcpy (temp,
00148                          this->timeprobes_,
00149                          this->max_size_ * sizeof (ACE_timeprobe_t));
00150 
00151          // Iterates over the array explicitly calling the destructor for
00152          // each probe instance, then deallocates the memory
00153 
00154          ACE_DES_ARRAY_FREE ((ACE_timeprobe_t *)(this->timeprobes_),
00155                              this->max_size_,
00156                              this->allocator ()->free,
00157                              ACE_timeprobe_t);
00158       }
00159       this->timeprobes_ = temp;
00160       this->max_size_ = size;
00161    }
00162 }
00163 
00164 template <class ACE_LOCK, class ALLOCATOR> ACE_Unbounded_Set<ACE_Event_Descriptions> &
00165 ACE_Timeprobe_Ex<ACE_LOCK, ALLOCATOR>::event_descriptions (void)
00166 {
00167   return this->event_descriptions_;
00168 }
00169 
00170 template <class ACE_LOCK, class ALLOCATOR> ACE_Unbounded_Set<ACE_Event_Descriptions> &
00171 ACE_Timeprobe_Ex<ACE_LOCK, ALLOCATOR>::sorted_event_descriptions (void)
00172 {
00173   return this->sorted_event_descriptions_;
00174 }
00175 
00176 template <class ACE_LOCK, class ALLOCATOR> ACE_timeprobe_t *
00177 ACE_Timeprobe_Ex<ACE_LOCK, ALLOCATOR>::timeprobes (void)
00178 {
00179   return this->timeprobes_;
00180 }
00181 
00182 template <class ACE_LOCK, class ALLOCATOR> ACE_LOCK &
00183 ACE_Timeprobe_Ex<ACE_LOCK, ALLOCATOR>::lock (void)
00184 {
00185   return this->lock_;
00186 }
00187 
00188 template <class ACE_LOCK, class ALLOCATOR> u_long
00189 ACE_Timeprobe_Ex<ACE_LOCK, ALLOCATOR>::max_size (void)
00190 {
00191   return this->max_size_;
00192 }
00193 
00194 template <class ACE_LOCK, class ALLOCATOR> u_long
00195 ACE_Timeprobe_Ex<ACE_LOCK, ALLOCATOR>::current_size (void)
00196 {
00197   return this->current_size_;
00198 }
00199 
00200 template <class ACE_LOCK, class ALLOCATOR> int
00201 ACE_Timeprobe_Ex<ACE_LOCK, ALLOCATOR>::event_descriptions (const char **descriptions,
00202                                              u_long minimum_id)
00203 {
00204   ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1);
00205 
00206   ACE_Event_Descriptions events;
00207   events.descriptions_ = descriptions;
00208   events.minimum_id_ = minimum_id;
00209 
00210   this->event_descriptions_.insert (events);
00211 
00212   return 0;
00213 }
00214 
00215 template <class ACE_LOCK, class ALLOCATOR> void
00216 ACE_Timeprobe_Ex<ACE_LOCK, ALLOCATOR>::print_times (void)
00217 {
00218   ACE_GUARD (ACE_LOCK, ace_mon, this->lock_);
00219 
00220   // Sort the event descriptions
00221   this->sort_event_descriptions_i ();
00222 
00223   ACE_DEBUG ((LM_DEBUG,
00224               "\nACE_Timeprobe_Ex; %d timestamps were recorded:\n",
00225               this->current_size_));
00226 
00227   if (this->current_size_ == 0)
00228     return;
00229 
00230   ACE_DEBUG ((LM_DEBUG,
00231               "\n%-50.50s %8.8s %13.13s\n\n",
00232               "Event",
00233               "thread",
00234               "usec"));
00235 
00236   ACE_DEBUG ((LM_DEBUG,
00237               "%-50.50s %8.8x %13.13s\n",
00238               this->find_description_i (0),
00239               this->timeprobes_[0].thread_,
00240               "START"));
00241 
00242   ACE_UINT32 gsf = ACE_High_Res_Timer::global_scale_factor ();
00243   u_long i, j;
00244 
00245   if (report_buffer_full_ == 0) {
00246     i = 1;
00247   }
00248   else {
00249     i = this->current_size_;
00250   }
00251 
00252   do
00253     {
00254       if (i == 0) {
00255         j = this->max_size_;
00256       }
00257       else {
00258         j = i - 1;
00259       }
00260 
00261       ACE_hrtime_t time_difference =
00262         this->timeprobes_[i].time_ - this->timeprobes_[j].time_;
00263 
00264       ACE_UINT32 elapsed_time_in_micro_seconds =
00265         (ACE_UINT32) (time_difference / gsf);
00266       ACE_UINT32 remainder =
00267         (ACE_UINT32) (time_difference % gsf);
00268       // Convert to the fractional part in microseconds, with 3 digits
00269       // of precision (hence the 1000).
00270       ACE_UINT32 fractional = remainder * 1000 / gsf;
00271 
00272       ACE_DEBUG ((LM_DEBUG,
00273                   "%-50.50s %8.8x %10u.%03.3u\n",
00274                   this->find_description_i (i),
00275                   this->timeprobes_[i].thread_,
00276                   (unsigned int) elapsed_time_in_micro_seconds,
00277                   (unsigned int) fractional));
00278 
00279       i = (i + 1) % this ->max_size_; // Modulus increment: loops around at the end.
00280 
00281     } while (i != this->current_size_);
00282 }
00283 
00284 template <class ACE_LOCK, class ALLOCATOR> void
00285 ACE_Timeprobe_Ex<ACE_LOCK, ALLOCATOR>::print_absolute_times (void)
00286 {
00287   ACE_GUARD (ACE_LOCK, ace_mon, this->lock_);
00288 
00289   // Sort the event descriptions
00290   this->sort_event_descriptions_i ();
00291 
00292   ACE_DEBUG ((LM_DEBUG,
00293               "\nACE_Timeprobe_Ex; %d timestamps were recorded:\n",
00294               this->current_size_));
00295 
00296   if (this->current_size_ == 0 && this->report_buffer_full_ == 0) {
00297     return;
00298   }
00299 
00300   ACE_DEBUG ((LM_DEBUG,
00301               "\n%-50.50s %8.8s %13.13s\n\n",
00302               "Event",
00303               "thread",
00304               "stamp"));
00305 
00306   u_long i;
00307   if (report_buffer_full_ == 0) {
00308     i = 1;
00309   }
00310   else {
00311     i = this->current_size_;
00312   }
00313 
00314   ACE_Time_Value tv; // to convert ACE_hrtime_t
00315   do
00316     {
00317       ACE_High_Res_Timer::hrtime_to_tv (tv, this->timeprobes_ [i].time_);
00318 
00319       ACE_DEBUG ((LM_DEBUG,
00320                   "%-50.50s %8.8x %12.12u\n",
00321                   this->find_description_i (i),
00322                   this->timeprobes_ [i].thread_,
00323                   tv.sec () * 1000000
00324                    + tv.usec ()));
00325       i = (i + 1) % this ->max_size_; // Modulus increment: loops around at the end.
00326 
00327     } while (i != this->current_size_);
00328 }
00329 
00330 template <class ACE_LOCK, class ALLOCATOR> const char *
00331 ACE_Timeprobe_Ex<ACE_LOCK, ALLOCATOR>::find_description_i (u_long i)
00332 {
00333   if (this->timeprobes_[i].event_type_ == ACE_timeprobe_t::STRING) {
00334     return this->timeprobes_[i].event_.event_description_;
00335   }
00336   else
00337     {
00338       EVENT_DESCRIPTIONS::iterator iterator = this->sorted_event_descriptions_.begin ();
00339       for (u_long j = 0;
00340            j < this->sorted_event_descriptions_.size () - 1;
00341            iterator++, j++)
00342         {
00343           EVENT_DESCRIPTIONS::iterator next_event_descriptions = iterator;
00344           ++next_event_descriptions;
00345 
00346           if (this->timeprobes_[i].event_.event_number_ < (*next_event_descriptions).minimum_id_)
00347             break;
00348         }
00349       return (*iterator).descriptions_[this->timeprobes_[i].event_.event_number_ - (*iterator).minimum_id_];
00350     }
00351 }
00352 
00353 template <class ACE_LOCK, class ALLOCATOR> void
00354 ACE_Timeprobe_Ex<ACE_LOCK, ALLOCATOR>::sort_event_descriptions_i (void)
00355 {
00356   size_t total_elements = this->event_descriptions_.size ();
00357 
00358   for (size_t i = 0;
00359        i < total_elements;
00360        i++)
00361     {
00362       EVENT_DESCRIPTIONS::iterator iterator = this->event_descriptions_.begin ();
00363       ACE_Event_Descriptions min_entry = *iterator;
00364 
00365       for (;
00366            iterator != this->event_descriptions_.end ();
00367            iterator++)
00368         if ((*iterator).minimum_id_ < min_entry.minimum_id_)
00369           min_entry = *iterator;
00370 
00371       this->sorted_event_descriptions_.insert (min_entry);
00372       this->event_descriptions_.remove (min_entry);
00373     }
00374 }
00375 
00376 template <class ACE_LOCK, class ALLOCATOR> ALLOCATOR *
00377 ACE_Timeprobe_Ex<ACE_LOCK, ALLOCATOR>::allocator (void)
00378 {
00379   return allocator_ ? allocator_ : ACE_Singleton<ALLOCATOR, ACE_LOCK>::instance ();
00380 }
00381 
00382 template <class Timeprobe>
00383 ACE_Function_Timeprobe<Timeprobe>::ACE_Function_Timeprobe (Timeprobe &timeprobe,
00384                                                            u_long event)
00385   : timeprobe_ (timeprobe),
00386     event_ (event)
00387 {
00388   this->timeprobe_.timeprobe (this->event_);
00389 }
00390 
00391 template <class Timeprobe>
00392 ACE_Function_Timeprobe<Timeprobe>::~ACE_Function_Timeprobe (void)
00393 {
00394   this->timeprobe_.timeprobe (this->event_ + 1);
00395 }
00396 
00397 ACE_END_VERSIONED_NAMESPACE_DECL
00398 
00399 #endif /* ACE_COMPILE_TIMEPROBES */
00400 #endif /* ACE_TIMEPROBE_T_CPP */

Generated on Thu Nov 9 09:42:07 2006 for ACE by doxygen 1.3.6