High_Res_Timer.cpp

Go to the documentation of this file.
00001 // High_Res_Timer.cpp,v 4.104 2006/01/04 09:39:14 jwillemsen Exp
00002 
00003 // Be very carefull before changing the calculations inside
00004 // ACE_High_Res_Timer.  The precision matters and we are using integer
00005 // calculations not floating point.  Also look good at the emulated 64
00006 // bit int class (inside Basic_Types{h,i,cpp} before changing
00007 // anything.  It's operator/ only returns 32 bits not 64 bits, among
00008 // other things.
00009 
00010 #include "ace/High_Res_Timer.h"
00011 
00012 #if !defined (__ACE_INLINE__)
00013 #include "ace/High_Res_Timer.inl"
00014 #endif /* __ACE_INLINE__ */
00015 
00016 #include "ace/Stats.h"
00017 #include "ace/OS_NS_stdio.h"
00018 #include "ace/OS_NS_string.h"
00019 #include "ace/OS_NS_sys_time.h"
00020 #include "ace/OS_NS_time.h"
00021 #include "ace/OS_NS_unistd.h"
00022 #include "ace/OS_NS_stdlib.h"
00023 
00024 ACE_RCSID(ace, High_Res_Timer, "High_Res_Timer.cpp,v 4.104 2006/01/04 09:39:14 jwillemsen Exp")
00025 
00026 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00027 
00028 ACE_ALLOC_HOOK_DEFINE(ACE_High_Res_Timer)
00029 
00030 ACE_END_VERSIONED_NAMESPACE_DECL
00031 
00032 // For Intel platforms, a scale factor is required for
00033 // ACE_OS::gethrtime.  We'll still set this to one to prevent division
00034 // by zero errors.
00035 #if (defined (ACE_WIN32) || defined (ACE_HAS_POWERPC_TIMER) || \
00036      defined (ACE_HAS_PENTIUM) || defined (ACE_HAS_ALPHA_TIMER)) && \
00037     !defined (ACE_HAS_HI_RES_TIMER)
00038 
00039 # include "ace/Guard_T.h"
00040 # include "ace/Recursive_Thread_Mutex.h"
00041 # include "ace/Object_Manager.h"
00042 
00043 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00044 
00045   // Initialize the global_scale_factor_ to 1.  The first
00046   // ACE_High_Res_Timer instance construction will override this
00047   // value.
00048   /* static */
00049   ACE_UINT32 ACE_High_Res_Timer::global_scale_factor_ = 1u;
00050 
00051 ACE_END_VERSIONED_NAMESPACE_DECL
00052 
00053 #else  /* ! (ACE_WIN32 || ACE_HAS_POWERPC_TIMER || \
00054              ACE_HAS_PENTIUM || ACE_HAS_ALPHA_TIMER)  ||
00055           ACE_HAS_HI_RES_TIMER */
00056 
00057 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00058 
00059   // A scale_factor of 1000 converts nanosecond ticks to microseconds.
00060   // That is, on these platforms, 1 tick == 1 nanosecond.
00061   /* static */
00062   ACE_UINT32 ACE_High_Res_Timer::global_scale_factor_ = 1000u;
00063 
00064 ACE_END_VERSIONED_NAMESPACE_DECL
00065 #endif /* ! (ACE_WIN32 || ACE_HAS_POWERPC_TIMER || \
00066              ACE_HAS_PENTIUM || ACE_HAS_ALPHA_TIMER)  ||
00067           ACE_HAS_HI_RES_TIMER */
00068 
00069 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00070 
00071 // This is used to tell if the global_scale_factor_ has been
00072 // set, and if high resolution timers are supported.
00073 /* static */
00074 int ACE_High_Res_Timer::global_scale_factor_status_ = 0;
00075 
00076 
00077 #if defined (linux)
00078 // Determine the apparent CPU clock speed from /proc/cpuinfo
00079 ACE_UINT32
00080 ACE_High_Res_Timer::get_cpuinfo (void)
00081 {
00082   ACE_UINT32 scale_factor = 1u;
00083 
00084   // Get the BogoMIPS from /proc/cpuinfo.  It works fine on Alpha and
00085   // Pentium Pro.  For other CPUs, it will be necessary to interpret
00086   // the BogoMips, as described in the BogoMips mini-HOWTO.  Note that
00087   // this code assumes an order to the /proc/cpuinfo contents.  The
00088   // BogoMips rating had better come after CPU type and model info.
00089 #if !defined (__alpha__)
00090   int supported = 0;
00091 #endif /* __alpha__ */
00092 
00093   FILE *cpuinfo = ACE_OS::fopen (ACE_LIB_TEXT ("/proc/cpuinfo"),
00094                                  ACE_LIB_TEXT ("r"));
00095 
00096   if (cpuinfo != 0)
00097     {
00098       char buf[128];
00099 
00100       // ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nReading /proc/cpuinfo...")));
00101 
00102       while (ACE_OS::fgets (buf, sizeof buf, cpuinfo))
00103         {
00104 #if defined (__alpha__)
00105           ACE_UINT32 whole;
00106           ACE_UINT32 fractional;
00107           if (::sscanf (buf,
00108                         "BogoMIPS : %d.%d\n",
00109                         &whole,
00110                         &fractional) == 2
00111               || ::sscanf (buf,
00112                            "bogomips : %d.%d\n",
00113                            &whole,
00114                            &fractional) == 2)
00115             {
00116               scale_factor = whole;
00117               break;
00118             }
00119 #else
00120           double mhertz = 1;
00121           double bmips = 1;
00122           char arg[128];
00123 
00124           // CPU type?
00125           if (::sscanf (buf, "cpu : %s\n", arg) == 1)
00126             {
00127               // If this is an Alpha chip, then the BogoMips rating is
00128               // usable...
00129               if (ACE_OS::strncmp (arg,
00130                                    "Alpha",
00131                                    5) == 0)
00132                 {
00133                   supported = 1;
00134                   // ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT (" recognized Alpha chip...")));
00135                 }
00136             }
00137           // Pentium CPU model?
00138           else if (supported == 0
00139                    && ::sscanf (buf, "model name : Pentium %s\n", arg) == 1)
00140             {
00141               // But if we don't have the right kind of Intel chip,
00142               // just quit.
00143               if (ACE_OS::strcmp (arg, "II") == 0
00144                   || ACE_OS::strcmp (arg, "III") == 0
00145                   || ACE_OS::strcmp (arg, "IV") == 0
00146                   || ACE_OS::strcmp (arg, "Pro") == 0)
00147                 {
00148                   supported = 1;
00149                   // ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT (" recognized Pentium Pro/II chip...")));
00150                 }
00151             }
00152           else if (::sscanf (buf, "cpu MHz : %lf\n", &mhertz) == 1)
00153             {
00154               // If the line "cpu MHz : xxx" is present, then it's a
00155               // reliable measure of the CPU speed - according to the
00156               // kernel-source.
00157               scale_factor = (ACE_UINT32) (mhertz + 0.5);
00158               break;
00159             }
00160           else if (::sscanf (buf, "bogomips : %lf\n", &bmips) == 1
00161                    || ::sscanf (buf, "BogoMIPS : %lf\n", &bmips) == 1)
00162             {
00163               if (supported)
00164                 {
00165                   scale_factor = (ACE_UINT32) (bmips + 0.5);
00166                   // ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT (" setting the clock scale factor to %u"), scale_factor));
00167                 }
00168 #if 0
00169               else
00170                 {
00171                   ACE_DEBUG ((LM_DEBUG,
00172                               ACE_LIB_TEXT ("\nThe BogoMIPS metric is not supported on this platform"
00173                                          "\n\tReport the results of the clock calibration and"
00174                                          "\n\tthe contents of /proc/cpuinfo to the ace-users mailing list")));
00175                 }
00176 #endif /* 0 */
00177               break;
00178             }
00179 #endif /* __alpha__ */
00180         }
00181 
00182       // ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT (" (done)\n")));
00183 
00184       ACE_OS::fclose (cpuinfo);
00185     }
00186 
00187   return scale_factor;
00188 }
00189 #endif /* linux */
00190 
00191 ACE_UINT32
00192 ACE_High_Res_Timer::global_scale_factor (void)
00193 {
00194 #if (defined (ACE_WIN32) || defined (ACE_HAS_POWERPC_TIMER) || \
00195      defined (ACE_HAS_PENTIUM) || defined (ACE_HAS_ALPHA_TIMER)) && \
00196     !defined (ACE_HAS_HI_RES_TIMER) && \
00197     ((defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)) || \
00198      defined (ghs) || defined (__GNUG__) || defined (__KCC) || \
00199      defined (__INTEL_COMPILER))
00200   // Check if the global scale factor needs to be set, and do if so.
00201   if (ACE_High_Res_Timer::global_scale_factor_status_ == 0)
00202     {
00203       // Grab ACE's static object lock.  This doesn't have anything to
00204       // do with static objects; it's just a convenient lock to use.
00205       ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
00206                                 *ACE_Static_Object_Lock::instance (), 0));
00207 
00208       // Double check
00209       if (ACE_High_Res_Timer::global_scale_factor_status_ == 0)
00210         {
00211 #         if defined (ACE_WIN32)
00212             LARGE_INTEGER freq;
00213             if (::QueryPerformanceFrequency (&freq))
00214               {
00215                 // We have a high-res timer
00216 #             if defined (ACE_LACKS_LONGLONG_T)
00217                 ACE_UINT64 uint64_freq(freq.u.LowPart, (ACE_UINT32) freq.u.HighPart);
00218                 ACE_High_Res_Timer::global_scale_factor
00219                   (uint64_freq / (ACE_UINT32) ACE_ONE_SECOND_IN_USECS);
00220 #             else
00221                 ACE_High_Res_Timer::global_scale_factor
00222                   (static_cast<unsigned int> (freq.QuadPart / ACE_HR_SCALE_CONVERSION));
00223 #             endif // (ACE_LACKS_LONGLONG_T)
00224 
00225                 ACE_High_Res_Timer::global_scale_factor_status_ = 1;
00226               }
00227             else
00228               // High-Res timers not supported
00229               ACE_High_Res_Timer::global_scale_factor_status_ = -1;
00230 
00231             return ACE_High_Res_Timer::global_scale_factor_;
00232 
00233 #         elif defined (linux)
00234             ACE_High_Res_Timer::global_scale_factor (ACE_High_Res_Timer::get_cpuinfo ());
00235 #         endif /* ! ACE_WIN32 && ! (linux && __alpha__) */
00236 
00237 #         if !defined (ACE_WIN32)
00238           if (ACE_High_Res_Timer::global_scale_factor_ == 1u)
00239             // Failed to retrieve CPU speed from system, so calculate it.
00240             ACE_High_Res_Timer::calibrate ();
00241 #         endif // (ACE_WIN32)
00242         }
00243     }
00244 
00245   ACE_High_Res_Timer::global_scale_factor_status_ = 1;
00246 #endif /* (ACE_WIN32 || ACE_HAS_POWERPC_TIMER || \
00247            ACE_HAS_PENTIUM || ACE_HAS_ALPHA_TIMER) && \
00248           ! ACE_HAS_HI_RES_TIMER &&
00249           ((WIN32 && ! WINCE) || ghs || __GNUG__) */
00250 
00251   return ACE_High_Res_Timer::global_scale_factor_;
00252 }
00253 
00254 ACE_High_Res_Timer::ACE_High_Res_Timer (void)
00255 {
00256   ACE_TRACE ("ACE_High_Res_Timer::ACE_High_Res_Timer");
00257 
00258   this->reset ();
00259 
00260   // Make sure that the global scale factor is set.
00261   (void) global_scale_factor ();
00262 }
00263 
00264 ACE_UINT32
00265 ACE_High_Res_Timer::calibrate (const ACE_UINT32 usec,
00266                                const u_int iterations)
00267 {
00268   const ACE_Time_Value sleep_time (0, usec);
00269   ACE_Stats delta_hrtime;
00270   // In units of 100 usec, to avoid overflow.
00271   ACE_Stats actual_sleeps;
00272 
00273   for (u_int i = 0;
00274        i < iterations;
00275        ++i)
00276     {
00277       const ACE_Time_Value actual_start =
00278         ACE_OS::gettimeofday ();
00279       const ACE_hrtime_t start =
00280         ACE_OS::gethrtime ();
00281       ACE_OS::sleep (sleep_time);
00282       const ACE_hrtime_t stop =
00283         ACE_OS::gethrtime ();
00284       const ACE_Time_Value actual_delta =
00285         ACE_OS::gettimeofday () - actual_start;
00286 
00287       // Store the sample.
00288       delta_hrtime.sample (ACE_HRTIME_CONVERSION (stop - start));
00289       actual_sleeps.sample (actual_delta.msec () * 100u);
00290     }
00291 
00292   // Calculate the mean value of the samples, with no fractional
00293   // precision.  Use it for the global scale factor.
00294   ACE_Stats_Value ticks (0);
00295   delta_hrtime.mean (ticks);
00296 
00297   ACE_Stats_Value actual_sleep (0);
00298   actual_sleeps.mean (actual_sleep);
00299 
00300   // The addition of 5 below rounds instead of truncates.
00301   const ACE_UINT32 scale_factor =
00302     (ticks.whole () / actual_sleep.whole () + 5) /
00303     10u /* usec/100 usec */;
00304   ACE_High_Res_Timer::global_scale_factor (scale_factor);
00305 
00306   return scale_factor;
00307 }
00308 
00309 void
00310 ACE_High_Res_Timer::dump (void) const
00311 {
00312 #if defined (ACE_HAS_DUMP)
00313   ACE_TRACE ("ACE_High_Res_Timer::dump");
00314 
00315   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00316   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nglobal_scale_factor_: %u\n"),
00317              global_scale_factor ()));
00318 #if defined (ACE_LACKS_LONGLONG_T)
00319   ACE_DEBUG ((LM_DEBUG,
00320              ACE_LIB_TEXT (":\nstart_.hi ():     %8x; start_.lo ():      %8x;\n")
00321              ACE_LIB_TEXT ("end_.hi ():       %8x; end_.lo ():        %8x;\n")
00322              ACE_LIB_TEXT ("total_.hi ():     %8x; total_.lo ():      %8x;\n")
00323              ACE_LIB_TEXT ("start_incr_.hi () %8x; start_incr_.lo (): %8x;\n"),
00324              start_.hi (), start_.lo (),
00325              end_.hi (), end_.lo (),
00326              total_.hi (), total_.lo (),
00327              start_incr_.hi (), start_incr_.lo ()));
00328 #else  /* ! ACE_LACKS_LONGLONG_T */
00329   ACE_DEBUG ((LM_DEBUG,
00330              ACE_LIB_TEXT (":\nstart_.hi ():     %8x; start_.lo ():      %8x;\n")
00331              ACE_LIB_TEXT ("end_.hi ():       %8x; end_.lo ():        %8x;\n")
00332              ACE_LIB_TEXT ("total_.hi ():     %8x; total_.lo ():      %8x;\n")
00333              ACE_LIB_TEXT ("start_incr_.hi () %8x; start_incr_.lo (): %8x;\n"),
00334              ACE_CU64_TO_CU32 (start_ >> 32),
00335              ACE_CU64_TO_CU32 (start_ & 0xfffffffful),
00336              ACE_CU64_TO_CU32 (end_ >> 32),
00337              ACE_CU64_TO_CU32 (end_ & 0xfffffffful),
00338              ACE_CU64_TO_CU32 (total_ >> 32),
00339              ACE_CU64_TO_CU32 (total_ & 0xfffffffful),
00340              ACE_CU64_TO_CU32 (start_incr_ >> 32),
00341              ACE_CU64_TO_CU32 (start_incr_ & 0xfffffffful)));
00342 #endif /* ! ACE_LACKS_LONGLONG_T */
00343   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00344 #endif /* ACE_HAS_DUMP */
00345 }
00346 
00347 void
00348 ACE_High_Res_Timer::reset (void)
00349 {
00350   ACE_TRACE ("ACE_High_Res_Timer::reset");
00351 
00352   this->start_ = 0;
00353   this->end_ = 0;
00354   this->total_ = 0;
00355   this->start_incr_ = 0;
00356 }
00357 
00358 void
00359 ACE_High_Res_Timer::elapsed_time (ACE_Time_Value &tv) const
00360 {
00361   hrtime_to_tv (tv,
00362                 ACE_High_Res_Timer::elapsed_hrtime (this->end_, this->start_));
00363 }
00364 
00365 #if defined (ACE_HAS_POSIX_TIME)
00366 // Note... Win32 does not have ACE_HAS_POSIX_TIME, so the scale factor
00367 // does not need to take into account the different units on Win32.
00368 
00369 void
00370 ACE_High_Res_Timer::elapsed_time (struct timespec &elapsed_time) const
00371 {
00372   // This implementation should be cleaned up.
00373 
00374   // Just grab the nanoseconds.  That is, leave off all values above
00375   // microsecond.  This equation is right!  Don't mess with me!  (It
00376   // first strips off everything but the portion less than 1 usec.
00377   // Then it converts that to nanoseconds by dividing by the scale
00378   // factor to convert to usec, and multiplying by 1000.)  The cast
00379   // avoids a MSVC 4.1 compiler warning about narrowing.
00380   ACE_hrtime_t elapsed =
00381     ACE_High_Res_Timer::elapsed_hrtime (this->end_, this->start_);
00382   u_long nseconds = static_cast<u_long> (elapsed %
00383                                          global_scale_factor () * 1000u /
00384                                          global_scale_factor ());
00385 
00386   // Get just the microseconds (dropping any left over nanoseconds).
00387   ACE_UINT32 useconds = (ACE_UINT32) (elapsed / global_scale_factor ());
00388 
00389   elapsed_time.tv_sec = (time_t) (useconds / ACE_ONE_SECOND_IN_USECS);
00390   // Transforms one second in microseconds into nanoseconds.
00391   elapsed_time.tv_nsec = (time_t) ((useconds % ACE_ONE_SECOND_IN_USECS) * 1000u + nseconds);
00392 }
00393 #endif /* ACE_HAS_POSIX_TIME */
00394 
00395 void
00396 ACE_High_Res_Timer::elapsed_time_incr (ACE_Time_Value &tv) const
00397 {
00398   hrtime_to_tv (tv, total_);
00399 }
00400 
00401 void
00402 ACE_High_Res_Timer::elapsed_time (ACE_hrtime_t &nanoseconds) const
00403 {
00404   // Please do _not_ rearrange this equation.  It is carefully
00405   // designed and tested to avoid overflow on machines that don't have
00406   // native 64-bit ints. In particular, division can be a problem.
00407   // For more background on this, please see bugzilla #1024.
00408 #if defined (ACE_WIN32)
00409   nanoseconds = ACE_High_Res_Timer::elapsed_hrtime (this->end_, this->start_)
00410             * (1024000000u / ACE_High_Res_Timer::global_scale_factor());
00411 #else
00412   nanoseconds = ACE_High_Res_Timer::elapsed_hrtime (this->end_, this->start_)
00413             * (1024000u / ACE_High_Res_Timer::global_scale_factor ());
00414 #endif /* ACE_WIN32 */
00415   // Caution - Borland has a problem with >>=, so resist the temptation.
00416   nanoseconds = nanoseconds >> 10;
00417   // Right shift is implemented for non native 64-bit ints
00418   // operator/ only for a 32 bit result !
00419 }
00420 
00421 void
00422 ACE_High_Res_Timer::elapsed_time_incr (ACE_hrtime_t &nanoseconds) const
00423 {
00424   // Same as above.
00425 #if defined (ACE_WIN32)
00426   nanoseconds = this->total_
00427             * (1024000000u / ACE_High_Res_Timer::global_scale_factor());
00428 #else
00429   nanoseconds = this->total_
00430             * (1024000u / ACE_High_Res_Timer::global_scale_factor ());
00431 #endif
00432   // Caution - Borland has a problem with >>=, so resist the temptation.
00433   nanoseconds = nanoseconds >> 10;
00434 }
00435 
00436 #if !defined (ACE_HAS_WINCE)
00437 void
00438 ACE_High_Res_Timer::print_ave (const ACE_TCHAR *str,
00439                                const int count,
00440                                ACE_HANDLE handle) const
00441 {
00442   ACE_TRACE ("ACE_High_Res_Timer::print_ave");
00443 
00444   // Get the total number of nanoseconds elapsed.
00445   ACE_hrtime_t total_nanoseconds;
00446   this->elapsed_time (total_nanoseconds);
00447 
00448   // Separate to seconds and nanoseconds.
00449   u_long total_secs =
00450     static_cast<u_long> (total_nanoseconds / (ACE_UINT32) ACE_ONE_SECOND_IN_NSECS);
00451   ACE_UINT32 extra_nsecs =
00452     static_cast<ACE_UINT32> (total_nanoseconds % (ACE_UINT32) ACE_ONE_SECOND_IN_NSECS);
00453 
00454   ACE_TCHAR buf[100];
00455   if (count > 1)
00456     {
00457       ACE_hrtime_t avg_nsecs = total_nanoseconds / (ACE_UINT32) count;
00458       ACE_OS::sprintf (buf,
00459                        ACE_LIB_TEXT (" count = %d, total (secs %lu, usecs %u), avg usecs = %lu\n"),
00460                        count,
00461                        total_secs,
00462                        (extra_nsecs + 500u) / 1000u,
00463                        (u_long) ((avg_nsecs + 500u) / 1000u));
00464     }
00465   else
00466     ACE_OS::sprintf (buf,
00467                      ACE_LIB_TEXT (" total %3lu.%06lu secs\n"),
00468                      total_secs,
00469                      (extra_nsecs + 500lu) / 1000lu);
00470 
00471   ACE_OS::write (handle,
00472                  str,
00473                  ACE_OS::strlen (str));
00474   ACE_OS::write (handle,
00475                  buf,
00476                  ACE_OS::strlen (buf));
00477 }
00478 
00479 void
00480 ACE_High_Res_Timer::print_total (const ACE_TCHAR *str,
00481                                  const int count,
00482                                  ACE_HANDLE handle) const
00483 {
00484   ACE_TRACE ("ACE_High_Res_Timer::print_total");
00485 
00486   // Get the total number of nanoseconds elapsed.
00487   ACE_hrtime_t total_nanoseconds;
00488   this->elapsed_time (total_nanoseconds);
00489 
00490   // Separate to seconds and nanoseconds.
00491   u_long total_secs =
00492     (u_long) (total_nanoseconds / (ACE_UINT32) ACE_ONE_SECOND_IN_NSECS);
00493   ACE_UINT32 extra_nsecs =
00494     (ACE_UINT32) (total_nanoseconds % (ACE_UINT32) ACE_ONE_SECOND_IN_NSECS);
00495 
00496   ACE_TCHAR buf[100];
00497   if (count > 1)
00498     {
00499       ACE_hrtime_t avg_nsecs = this->total_ / (ACE_UINT32) count;
00500 
00501       ACE_OS::sprintf (buf,
00502                        ACE_LIB_TEXT (" count = %d, total (secs %lu, usecs %u), avg usecs = %lu\n"),
00503                        count,
00504                        total_secs,
00505                        (extra_nsecs + 500u) / 1000u,
00506                        (u_long) ((avg_nsecs + 500u) / 1000u));
00507     }
00508   else
00509     ACE_OS::sprintf (buf,
00510                      ACE_LIB_TEXT (" total %3lu.%06u secs\n"),
00511                      total_secs,
00512                      (extra_nsecs + 500u) / 1000u);
00513 
00514   ACE_OS::write (handle,
00515                  str,
00516                  ACE_OS::strlen (str));
00517   ACE_OS::write (handle,
00518                  buf,
00519                  ACE_OS::strlen (buf));
00520 }
00521 #endif /* !ACE_HAS_WINCE */
00522 
00523 int
00524 ACE_High_Res_Timer::get_env_global_scale_factor (const ACE_TCHAR *env)
00525 {
00526 #if !defined (ACE_HAS_WINCE)
00527   if (env != 0)
00528     {
00529       const char *env_value = ACE_OS::getenv (ACE_TEXT_ALWAYS_CHAR (env));
00530       if (env_value != 0)
00531         {
00532           int value = ACE_OS::atoi (env_value);
00533           if (value > 0)
00534             {
00535               ACE_High_Res_Timer::global_scale_factor (value);
00536               return 0;
00537             }
00538         }
00539     }
00540 #else
00541   ACE_UNUSED_ARG (env);
00542 #endif /* !ACE_HAS_WINCE */
00543   return -1;
00544 }
00545 
00546 ACE_END_VERSIONED_NAMESPACE_DECL

Generated on Thu Nov 9 09:41:52 2006 for ACE by doxygen 1.3.6