OS_NS_time.inl

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // $Id: OS_NS_time.inl 80826 2008-03-04 14:51:23Z wotte $
00004 
00005 #include "ace/OS_NS_string.h"
00006 #include "ace/OS_NS_errno.h"
00007 #include "ace/Time_Value.h"
00008 #include "ace/OS_NS_unistd.h"
00009 #include "ace/OS_NS_sys_time.h"
00010 
00011 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00012 
00013 ACE_INLINE char *
00014 ACE_OS::asctime (const struct tm *t)
00015 {
00016   ACE_OS_TRACE ("ACE_OS::asctime");
00017 #if defined (ACE_LACKS_ASCTIME)
00018   ACE_UNUSED_ARG (t);
00019   ACE_NOTSUP_RETURN (0);
00020 #else
00021   ACE_OSCALL_RETURN (ACE_STD_NAMESPACE::asctime (t), char *, 0);
00022 #endif /* ACE_LACKS_ASCTIME */
00023 }
00024 
00025 ACE_INLINE char *
00026 ACE_OS::asctime_r (const struct tm *t, char *buf, int buflen)
00027 {
00028   ACE_OS_TRACE ("ACE_OS::asctime_r");
00029 #if defined (ACE_HAS_REENTRANT_FUNCTIONS)
00030 # if defined (ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R)
00031   char *result;
00032 #   if defined (DIGITAL_UNIX)
00033   ACE_OSCALL (::_Pasctime_r (t, buf), char *, 0, result);
00034 #   else
00035   ACE_OSCALL (::asctime_r (t, buf), char *, 0, result);
00036 #   endif /* DIGITAL_UNIX */
00037   ACE_OS::strsncpy (buf, result, buflen);
00038   return buf;
00039 # else
00040 #   if defined (ACE_HAS_SIZET_PTR_ASCTIME_R_AND_CTIME_R)
00041   ACE_OSCALL_RETURN (::asctime_r (t, buf, reinterpret_cast<size_t*>(&buflen)), char *, 0);
00042 #   else
00043   ACE_OSCALL_RETURN (::asctime_r (t, buf, buflen), char *, 0);
00044 #   endif /* ACE_HAS_SIZET_PTR_ASCTIME_R_AND_CTIME_R */
00045 # endif /* ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R */
00046 #elif defined (ACE_LACKS_ASCTIME_R)
00047   ACE_UNUSED_ARG (t);
00048   ACE_UNUSED_ARG (buf);
00049   ACE_UNUSED_ARG (buflen);
00050   ACE_NOTSUP_RETURN (0);
00051 #elif defined (ACE_HAS_TR24731_2005_CRT)
00052   char *result = buf;
00053   ACE_SECURECRTCALL (asctime_s (buf, static_cast<size_t> (buflen), t), \
00054                      char*, 0, result);
00055   return result;
00056 #else
00057   char *result = 0;
00058   ACE_OSCALL (ACE_STD_NAMESPACE::asctime (t), char *, 0, result);
00059   ACE_OS::strsncpy (buf, result, buflen);
00060   return buf;
00061 #endif /* ACE_HAS_REENTRANT_FUNCTIONS */
00062 }
00063 
00064 ACE_INLINE int
00065 ACE_OS::clock_gettime (clockid_t clockid, struct timespec *ts)
00066 {
00067   ACE_OS_TRACE ("ACE_OS::clock_gettime");
00068 #if defined (ACE_HAS_CLOCK_GETTIME)
00069   ACE_OSCALL_RETURN (::clock_gettime (clockid, ts), int, -1);
00070 #else
00071   ACE_UNUSED_ARG (clockid);
00072   ACE_UNUSED_ARG (ts);
00073   ACE_NOTSUP_RETURN (-1);
00074 #endif /* ACE_HAS_CLOCK_GETTIME */
00075 }
00076 
00077 ACE_INLINE int
00078 ACE_OS::clock_settime (clockid_t clockid, const struct timespec *ts)
00079 {
00080 #if defined (ACE_HAS_CLOCK_SETTIME)
00081 #  if defined (ACE_HAS_NONCONST_CLOCK_SETTIME)
00082   ACE_OSCALL_RETURN (::clock_settime (clockid, const_cast<struct timespec *>(ts)), int, -1);
00083 #  else
00084   ACE_OSCALL_RETURN (::clock_settime (clockid, ts), int, -1);
00085 #  endif /* ACE_HAS_NONCONST_CLOCK_SETTIME */
00086 #else
00087   ACE_UNUSED_ARG (clockid);
00088   ACE_UNUSED_ARG (ts);
00089   ACE_NOTSUP_RETURN (-1);
00090 #endif /* ACE_HAS_CLOCK_SETTIME */
00091 }
00092 
00093 // Magic number declaration and definition for ctime and ctime_r ()
00094 static const int ctime_buf_size = 26;
00095 
00096 ACE_INLINE ACE_TCHAR *
00097 ACE_OS::ctime (const time_t *t)
00098 {
00099   ACE_OS_TRACE ("ACE_OS::ctime");
00100 #if defined (ACE_HAS_BROKEN_CTIME)
00101   ACE_OSCALL_RETURN (::asctime (::localtime (t)), char *, 0);
00102 #elif defined (ACE_HAS_WINCE)
00103   static ACE_TCHAR buf [ctime_buf_size];
00104   return ACE_OS::ctime_r (t,
00105                           buf,
00106                           ctime_buf_size);
00107 #elif defined (ACE_WIN32) && defined (ACE_USES_WCHAR)
00108   ACE_OSCALL_RETURN (::_wctime (t), wchar_t *, 0);
00109 #else
00110 #  if defined (ACE_USES_WCHAR)   /* Not Win32, else it would do the above */
00111   char *narrow_time;
00112   ACE_OSCALL (::ctime (t), char *, 0, narrow_time);
00113   if (narrow_time == 0)
00114     return 0;
00115   // ACE_Ascii_To_Wide::convert allocates (via new []) a wchar_t[]. If
00116   // we've done this before, free the previous one. Yes, this leaves a
00117   // small memory leak (26 characters) but there's no way around this
00118   // that I know of. (Steve Huston, 12-Feb-2003).
00119   static wchar_t *wide_time = 0;
00120   if (wide_time != 0)
00121     delete [] wide_time;
00122   wide_time = ACE_Ascii_To_Wide::convert (narrow_time);
00123   return wide_time;
00124 #  else
00125   ACE_OSCALL_RETURN (::ctime (t), char *, 0);
00126 #  endif /* ACE_USES_WCHAR */
00127 # endif /* ACE_HAS_BROKEN_CTIME */
00128 }
00129 
00130 #if !defined (ACE_HAS_WINCE)  /* CE version in OS.cpp */
00131 ACE_INLINE ACE_TCHAR *
00132 ACE_OS::ctime_r (const time_t *t, ACE_TCHAR *buf, int buflen)
00133 {
00134   ACE_OS_TRACE ("ACE_OS::ctime_r");
00135 
00136 #if defined (ACE_HAS_REENTRANT_FUNCTIONS)
00137 
00138   char *bufp = 0;
00139 #   if defined (ACE_USES_WCHAR)
00140   char narrow_buf[ctime_buf_size];
00141   bufp = narrow_buf;
00142 #   else
00143   bufp = buf;
00144 #   endif /* ACE_USES_WCHAR */
00145 
00146   if (buflen < ctime_buf_size)
00147     {
00148       errno = ERANGE;
00149       return 0;
00150     }
00151 #   if defined (ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R)
00152 #      if defined (DIGITAL_UNIX)
00153   ACE_OSCALL (::_Pctime_r (t, bufp), ACE_TCHAR *, 0, bufp);
00154 #      else /* DIGITAL_UNIX */
00155   ACE_OSCALL (::ctime_r (t, bufp), char *, 0, bufp);
00156 #      endif /* DIGITAL_UNIX */
00157 #   else /* ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R */
00158 
00159 #      if defined (ACE_HAS_SIZET_PTR_ASCTIME_R_AND_CTIME_R)
00160   bufp = ::ctime_r (t, bufp, reinterpret_cast<size_t*>(&buflen));
00161 #      else /* ACE_CTIME_R_RETURNS_INT */
00162   bufp = ::ctime_r (t, bufp, buflen);
00163 #      endif /* ACE_CTIME_R_RETURNS_INT */
00164 
00165 #   endif /* ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R */
00166 
00167   if (bufp == 0)
00168     return 0;
00169 
00170 #   if defined (ACE_USES_WCHAR)
00171   ACE_Ascii_To_Wide wide_buf (bufp);
00172   ACE_OS_String::strcpy (buf, wide_buf.wchar_rep ());
00173   return buf;
00174 #   else
00175   return bufp;
00176 #   endif /* ACE_USES_WCHAR */
00177 
00178 #elif defined (ACE_HAS_TR24731_2005_CRT)
00179   if (buflen < ctime_buf_size)
00180     {
00181       errno = ERANGE;
00182       return 0;
00183     }
00184   ACE_TCHAR *result = buf;
00185 #  if defined (ACE_USES_WCHAR)
00186   ACE_SECURECRTCALL (_wctime_s (buf, buflen, t), wchar_t *, 0, result);
00187 #  else
00188   ACE_SECURECRTCALL (ctime_s (buf, buflen, t), char *, 0, result);
00189 #  endif
00190   return result;
00191 
00192 #else /* ACE_HAS_REENTRANT_FUNCTIONS */
00193   if (buflen < ctime_buf_size)
00194     {
00195       errno = ERANGE;
00196       return 0;
00197     }
00198 
00199   ACE_TCHAR *result;
00200 #     if defined (ACE_USES_WCHAR)
00201   ACE_OSCALL (::_wctime (t), wchar_t *, 0, result);
00202 #     else /* ACE_USES_WCHAR */
00203   ACE_OSCALL (::ctime (t), char *, 0, result);
00204 #     endif /* ACE_USES_WCHAR */
00205   if (result != 0)
00206     ACE_OS::strsncpy (buf, result, buflen);
00207   return buf;
00208 #endif /* ACE_HAS_REENTRANT_FUNCTIONS */
00209 }
00210 #endif /* !ACE_HAS_WINCE */
00211 
00212 #if !defined (ACE_LACKS_DIFFTIME)
00213 ACE_INLINE double
00214 ACE_OS::difftime (time_t t1, time_t t0)
00215 {
00216   return ::ace_difftime (t1, t0);
00217 }
00218 #endif /* ! ACE_LACKS_DIFFTIME */
00219 
00220 #if defined (ghs) && defined (ACE_HAS_PENTIUM) && !defined (ACE_WIN32)
00221   extern "C" ACE_hrtime_t ACE_GETHRTIME_NAME ();
00222 #endif /* ghs && ACE_HAS_PENTIUM */
00223 
00224 ACE_INLINE ACE_hrtime_t
00225 ACE_OS::gethrtime (const ACE_HRTimer_Op op)
00226 {
00227   ACE_OS_TRACE ("ACE_OS::gethrtime");
00228 #if defined (ACE_HAS_HI_RES_TIMER)
00229   ACE_UNUSED_ARG (op);
00230   return ::gethrtime ();
00231 #elif defined (ACE_HAS_AIX_HI_RES_TIMER)
00232   ACE_UNUSED_ARG (op);
00233   timebasestruct_t tb;
00234 
00235   ::read_real_time(&tb, TIMEBASE_SZ);
00236   ::time_base_to_time(&tb, TIMEBASE_SZ);
00237 
00238   return ACE_hrtime_t(tb.tb_high) * ACE_ONE_SECOND_IN_NSECS + tb.tb_low;
00239 #elif defined (ACE_WIN32)
00240   ACE_UNUSED_ARG(op);
00241   LARGE_INTEGER freq;
00242 
00243   ::QueryPerformanceCounter (&freq);
00244 
00245 #  if defined (ACE_LACKS_LONGLONG_T)
00246   ACE_UINT64 uint64_freq (freq.u.LowPart,
00247                           static_cast<unsigned int> (freq.u.HighPart));
00248   return uint64_freq;
00249 #  else
00250   return freq.QuadPart;
00251 #  endif //ACE_LACKS_LONGLONG_T
00252 #elif defined (ghs) && defined (ACE_HAS_PENTIUM)
00253   ACE_UNUSED_ARG (op);
00254   // Use .obj/gethrtime.o, which was compiled with g++.
00255   return ACE_GETHRTIME_NAME ();
00256 #elif (defined (__GNUG__) || defined (__INTEL_COMPILER)) && !defined(ACE_VXWORKS) && defined (ACE_HAS_PENTIUM)
00257   ACE_UNUSED_ARG (op);
00258 # if defined (ACE_LACKS_LONGLONG_T)
00259   double now;
00260 # else  /* ! ACE_LACKS_LONGLONG_T */
00261   ACE_hrtime_t now;
00262 # endif /* ! ACE_LACKS_LONGLONG_T */
00263 
00264 #if defined (__amd64__) || defined (__x86_64__)
00265   // Read the high res tick counter into 32 bit int variables "eax" and 
00266   // "edx", and then combine them into 64 bit int "now"
00267   ACE_UINT32 eax, edx;
00268   asm volatile ("rdtsc" : "=a" (eax), "=d" (edx) : : "memory");
00269   now = (((ACE_UINT64) eax) | (((ACE_UINT64) edx) << 32));
00270 #else
00271   // Read the high-res tick counter directly into memory variable "now".
00272   // The A constraint signifies a 64-bit int.
00273   asm volatile ("rdtsc" : "=A" (now) : : "memory");
00274 #endif
00275 
00276 # if defined (ACE_LACKS_LONGLONG_T)
00277   ACE_UINT32 least, most;
00278   ACE_OS::memcpy (&least, &now, sizeof (ACE_UINT32));
00279   ACE_OS::memcpy (&most, (u_char *) &now + sizeof (ACE_UINT32),
00280                   sizeof (ACE_UINT32));
00281 
00282   ACE_hrtime_t ret (least, most);
00283   return ret;
00284 # else  /* ! ACE_LACKS_LONGLONG_T */
00285   return now;
00286 # endif /* ! ACE_LACKS_LONGLONG_T */
00287 #elif defined (linux) && defined (ACE_HAS_ALPHA_TIMER)
00288   // NOTE:  alphas only have a 32 bit tick (cycle) counter.  The rpcc
00289   // instruction actually reads 64 bits, but the high 32 bits are
00290   // implementation-specific.  Linux and Digital Unix, for example,
00291   // use them for virtual tick counts, i.e., taking into account only
00292   // the time that the process was running.  This information is from
00293   // David Mosberger's article, see comment below.
00294   ACE_UINT32 now;
00295 
00296   // The following statement is based on code published by:
00297   // Mosberger, David, "How to Make Your Applications Fly, Part 1",
00298   // Linux Journal Issue 42, October 1997, page 50.  It reads the
00299   // high-res tick counter directly into the memory variable.
00300   asm volatile ("rpcc %0" : "=r" (now) : : "memory");
00301 
00302   return now;
00303 #elif defined (ACE_HAS_POWERPC_TIMER) && (defined (ghs) || defined (__GNUG__))
00304   // PowerPC w/ GreenHills or g++.
00305 
00306   ACE_UNUSED_ARG (op);
00307   u_long most;
00308   u_long least;
00309 
00310 #if defined (ghs)
00311   ACE_OS::readPPCTimeBase (most, least);
00312 #else
00313   u_long scratch;
00314 
00315   do {
00316     asm volatile ("mftbu %0\n"
00317           "mftb  %1\n"
00318           "mftbu %2"
00319           : "=r" (most), "=r" (least), "=r" (scratch));
00320   } while (most != scratch);
00321 #endif
00322 
00323 #if defined (ACE_LACKS_LONGLONG_T)
00324   return ACE_U_LongLong (least, most);
00325 #else  /* ! ACE_LACKS_LONGLONG_T */
00326   return 0x100000000llu * most  +  least;
00327 #endif /* ! ACE_LACKS_LONGLONG_T */
00328 
00329 #elif defined (ACE_HAS_CLOCK_GETTIME)
00330   // e.g., VxWorks (besides POWERPC && GreenHills) . . .
00331   ACE_UNUSED_ARG (op);
00332   struct timespec ts;
00333 
00334   ACE_OS::clock_gettime (
00335 #if defined (ACE_HAS_CLOCK_GETTIME_MONOTONIC)
00336          CLOCK_MONOTONIC,
00337 #endif /* !ACE_HAS_CLOCK_GETTIME_MONOTONIC */
00338          CLOCK_REALTIME,
00339          &ts);
00340 
00341   // Carefully create the return value to avoid arithmetic overflow
00342   // if ACE_hrtime_t is ACE_U_LongLong.
00343   return static_cast<ACE_hrtime_t> (ts.tv_sec) *
00344     ACE_U_ONE_SECOND_IN_NSECS  +  static_cast<ACE_hrtime_t> (ts.tv_nsec);
00345 #else
00346   ACE_UNUSED_ARG (op);
00347   ACE_Time_Value const now = ACE_OS::gettimeofday ();
00348 
00349   // Carefully create the return value to avoid arithmetic overflow
00350   // if ACE_hrtime_t is ACE_U_LongLong.
00351   return (static_cast<ACE_hrtime_t> (now.sec ()) * (ACE_UINT32) 1000000  +
00352           static_cast<ACE_hrtime_t> (now.usec ())) * (ACE_UINT32) 1000;
00353 #endif /* ACE_HAS_HI_RES_TIMER */
00354 }
00355 
00356 ACE_INLINE struct tm *
00357 ACE_OS::gmtime (const time_t *t)
00358 {
00359   ACE_OS_TRACE ("ACE_OS::gmtime");
00360 #if defined (ACE_LACKS_GMTIME)
00361   ACE_UNUSED_ARG (t);
00362   ACE_NOTSUP_RETURN (0);
00363 #else
00364   ACE_OSCALL_RETURN (::gmtime (t), struct tm *, 0);
00365 #endif /* ACE_LACKS_GMTIME */
00366 }
00367 
00368 ACE_INLINE struct tm *
00369 ACE_OS::gmtime_r (const time_t *t, struct tm *res)
00370 {
00371   ACE_OS_TRACE ("ACE_OS::gmtime_r");
00372 #if defined (ACE_HAS_REENTRANT_FUNCTIONS)
00373 # if defined (DIGITAL_UNIX)
00374   ACE_OSCALL_RETURN (::_Pgmtime_r (t, res), struct tm *, 0);
00375 # else
00376   ACE_OSCALL_RETURN (::gmtime_r (t, res), struct tm *, 0);
00377 # endif /* DIGITAL_UNIX */
00378 #elif defined (ACE_HAS_TR24731_2005_CRT)
00379   struct tm *tm_p = res;
00380   ACE_SECURECRTCALL (gmtime_s (res, t), struct tm *, 0, tm_p);
00381   return tm_p;
00382 #elif defined (ACE_LACKS_GMTIME_R)
00383   ACE_UNUSED_ARG (t);
00384   ACE_UNUSED_ARG (res);
00385   ACE_NOTSUP_RETURN (0);
00386 #else
00387   struct tm *result;
00388   ACE_OSCALL (::gmtime (t), struct tm *, 0, result) ;
00389   if (result != 0)
00390     *res = *result;
00391   return res;
00392 #endif /* ACE_HAS_REENTRANT_FUNCTIONS */
00393 }
00394 
00395 ACE_INLINE struct tm *
00396 ACE_OS::localtime (const time_t *t)
00397 {
00398   ACE_OS_TRACE ("ACE_OS::localtime");
00399 #if defined (ACE_LACKS_LOCALTIME)
00400   ACE_UNUSED_ARG (t);
00401   ACE_NOTSUP_RETURN (0);
00402 #else
00403   ACE_OSCALL_RETURN (::localtime (t), struct tm *, 0);
00404 #endif /* ACE_LACKS_LOCALTIME */
00405 }
00406 
00407 ACE_INLINE int
00408 ACE_OS::nanosleep (const struct timespec *requested,
00409                    struct timespec *remaining)
00410 {
00411   ACE_OS_TRACE ("ACE_OS::nanosleep");
00412 #if defined (ACE_HAS_CLOCK_GETTIME)
00413   // ::nanosleep () is POSIX 1003.1b.  So is ::clock_gettime ().  So,
00414   // if ACE_HAS_CLOCK_GETTIME is defined, then ::nanosleep () should
00415   // be available on the platform.  On Solaris 2.x, both functions
00416   // require linking with -lposix4.
00417   return ::nanosleep ((ACE_TIMESPEC_PTR) requested, remaining);
00418 #else
00419   ACE_UNUSED_ARG (remaining);
00420 
00421   // Convert into seconds and microseconds.
00422   ACE_Time_Value tv (requested->tv_sec,
00423                      requested->tv_nsec / 1000);
00424   return ACE_OS::sleep (tv);
00425 #endif /* ACE_HAS_CLOCK_GETTIME */
00426 }
00427 
00428 ACE_INLINE size_t
00429 ACE_OS::strftime (char *s, size_t maxsize, const char *format,
00430                   const struct tm *timeptr)
00431 {
00432 #if defined (ACE_LACKS_STRFTIME)
00433   ACE_UNUSED_ARG (s);
00434   ACE_UNUSED_ARG (maxsize);
00435   ACE_UNUSED_ARG (format);
00436   ACE_UNUSED_ARG (timeptr);
00437   ACE_NOTSUP_RETURN (0);
00438 #else
00439   return ACE_STD_NAMESPACE::strftime (s, maxsize, format, timeptr);
00440 #endif /* ACE_LACKS_STRFTIME */
00441 }
00442 
00443 ACE_INLINE char *
00444 ACE_OS::strptime (const char *buf, const char *format, struct tm *tm)
00445 {
00446 #if defined (ACE_LACKS_STRPTIME)
00447 #  if defined (ACE_REFUSE_STRPTIME_EMULATION)
00448   ACE_UNUSED_ARG (buf);
00449   ACE_UNUSED_ARG (format);
00450   ACE_UNUSED_ARG (tm);
00451   ACE_NOTSUP_RETURN (0);
00452 #  else
00453   return ACE_OS::strptime_emulation (buf, format, tm);
00454 #  endif /* ACE_REFUSE_STRPTIME_EMULATION */
00455 #else
00456   return ::strptime (buf, format, tm);
00457 #endif /* ACE_LACKS_STRPTIME */
00458 }
00459 
00460 ACE_INLINE time_t
00461 ACE_OS::time (time_t *tloc)
00462 {
00463   ACE_OS_TRACE ("ACE_OS::time");
00464 #if !defined (ACE_HAS_WINCE)
00465   ACE_OSCALL_RETURN (::time (tloc), time_t, (time_t) -1);
00466 #else
00467   time_t retv = ACE_OS::gettimeofday ().sec ();
00468   if (tloc)
00469     *tloc = retv;
00470   return retv;
00471 #endif /* ACE_HAS_WINCE */
00472 }
00473 
00474 // Linux won't compile unless we explicitly use a namespace here.
00475 #if defined (__GNUG__)
00476 namespace ACE_OS {
00477   ACE_INLINE long
00478   timezone (void)
00479   {
00480     return ::ace_timezone ();
00481   }
00482 } /* namespace ACE_OS */
00483 #else
00484 ACE_INLINE long
00485 ACE_OS::timezone (void)
00486 {
00487   return ::ace_timezone ();
00488 }
00489 #endif /* linux */
00490 
00491 ACE_INLINE void
00492 ACE_OS::tzset (void)
00493 {
00494 #if !defined (ACE_HAS_WINCE) && !defined (ACE_VXWORKS) && !defined(ACE_HAS_RTEMS) && !defined (ACE_HAS_DINKUM_STL)
00495 #   if defined (ACE_WIN32)
00496   ::_tzset ();  // For Win32.
00497 #   else
00498   ::tzset ();   // For UNIX platforms.
00499 #   endif /* ACE_WIN32 */
00500 # else
00501   errno = ENOTSUP;
00502 # endif /* ACE_HAS_WINCE && !VXWORKS && !ACE_HAS_RTEMS && !ACE_HAS_DINKUM_STL */
00503 }
00504 
00505 ACE_END_VERSIONED_NAMESPACE_DECL

Generated on Tue Feb 2 17:18:41 2010 for ACE by  doxygen 1.4.7