00001
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
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
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
00089
00090 if (this->current_size_ >= this->max_size_)
00091 {
00092 this->current_size_ = 0;
00093 this->report_buffer_full_ = 1;
00094 }
00095 # endif
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
00152
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
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
00269
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_;
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
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;
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_;
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
00400 #endif