3 // $Id: OS_NS_time.inl 80826 2008-03-04 14:51:23Z wotte $
5 #include "ace/OS_NS_string.h"
6 #include "ace/OS_NS_errno.h"
7 #include "ace/Time_Value.h"
8 #include "ace/OS_NS_unistd.h"
9 #include "ace/OS_NS_sys_time.h"
11 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
14 ACE_OS::asctime (const struct tm *t)
16 ACE_OS_TRACE ("ACE_OS::asctime");
17 #if defined (ACE_LACKS_ASCTIME)
19 ACE_NOTSUP_RETURN (0);
21 ACE_OSCALL_RETURN (ACE_STD_NAMESPACE::asctime (t), char *, 0);
22 #endif /* ACE_LACKS_ASCTIME */
26 ACE_OS::asctime_r (const struct tm *t, char *buf, int buflen)
28 ACE_OS_TRACE ("ACE_OS::asctime_r");
29 #if defined (ACE_HAS_REENTRANT_FUNCTIONS)
30 # if defined (ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R)
32 # if defined (DIGITAL_UNIX)
33 ACE_OSCALL (::_Pasctime_r (t, buf), char *, 0, result);
35 ACE_OSCALL (::asctime_r (t, buf), char *, 0, result);
36 # endif /* DIGITAL_UNIX */
37 ACE_OS::strsncpy (buf, result, buflen);
40 # if defined (ACE_HAS_SIZET_PTR_ASCTIME_R_AND_CTIME_R)
41 ACE_OSCALL_RETURN (::asctime_r (t, buf, reinterpret_cast<size_t*>(&buflen)), char *, 0);
43 ACE_OSCALL_RETURN (::asctime_r (t, buf, buflen), char *, 0);
44 # endif /* ACE_HAS_SIZET_PTR_ASCTIME_R_AND_CTIME_R */
45 # endif /* ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R */
46 #elif defined (ACE_LACKS_ASCTIME_R)
49 ACE_UNUSED_ARG (buflen);
50 ACE_NOTSUP_RETURN (0);
51 #elif defined (ACE_HAS_TR24731_2005_CRT)
53 ACE_SECURECRTCALL (asctime_s (buf, static_cast<size_t> (buflen), t), \
58 ACE_OSCALL (ACE_STD_NAMESPACE::asctime (t), char *, 0, result);
59 ACE_OS::strsncpy (buf, result, buflen);
61 #endif /* ACE_HAS_REENTRANT_FUNCTIONS */
65 ACE_OS::clock_gettime (clockid_t clockid, struct timespec *ts)
67 ACE_OS_TRACE ("ACE_OS::clock_gettime");
68 #if defined (ACE_HAS_CLOCK_GETTIME)
69 ACE_OSCALL_RETURN (::clock_gettime (clockid, ts), int, -1);
71 ACE_UNUSED_ARG (clockid);
73 ACE_NOTSUP_RETURN (-1);
74 #endif /* ACE_HAS_CLOCK_GETTIME */
78 ACE_OS::clock_settime (clockid_t clockid, const struct timespec *ts)
80 #if defined (ACE_HAS_CLOCK_SETTIME)
81 # if defined (ACE_HAS_NONCONST_CLOCK_SETTIME)
82 ACE_OSCALL_RETURN (::clock_settime (clockid, const_cast<struct timespec *>(ts)), int, -1);
84 ACE_OSCALL_RETURN (::clock_settime (clockid, ts), int, -1);
85 # endif /* ACE_HAS_NONCONST_CLOCK_SETTIME */
87 ACE_UNUSED_ARG (clockid);
89 ACE_NOTSUP_RETURN (-1);
90 #endif /* ACE_HAS_CLOCK_SETTIME */
93 // Magic number declaration and definition for ctime and ctime_r ()
94 static const int ctime_buf_size = 26;
96 ACE_INLINE ACE_TCHAR *
97 ACE_OS::ctime (const time_t *t)
99 ACE_OS_TRACE ("ACE_OS::ctime");
100 #if defined (ACE_HAS_BROKEN_CTIME)
101 ACE_OSCALL_RETURN (::asctime (::localtime (t)), char *, 0);
102 #elif defined (ACE_HAS_WINCE)
103 static ACE_TCHAR buf [ctime_buf_size];
104 return ACE_OS::ctime_r (t,
107 #elif defined (ACE_WIN32) && defined (ACE_USES_WCHAR)
108 ACE_OSCALL_RETURN (::_wctime (t), wchar_t *, 0);
110 # if defined (ACE_USES_WCHAR) /* Not Win32, else it would do the above */
112 ACE_OSCALL (::ctime (t), char *, 0, narrow_time);
113 if (narrow_time == 0)
115 // ACE_Ascii_To_Wide::convert allocates (via new []) a wchar_t[]. If
116 // we've done this before, free the previous one. Yes, this leaves a
117 // small memory leak (26 characters) but there's no way around this
118 // that I know of. (Steve Huston, 12-Feb-2003).
119 static wchar_t *wide_time = 0;
122 wide_time = ACE_Ascii_To_Wide::convert (narrow_time);
125 ACE_OSCALL_RETURN (::ctime (t), char *, 0);
126 # endif /* ACE_USES_WCHAR */
127 # endif /* ACE_HAS_BROKEN_CTIME */
130 #if !defined (ACE_HAS_WINCE) /* CE version in OS.cpp */
131 ACE_INLINE ACE_TCHAR *
132 ACE_OS::ctime_r (const time_t *t, ACE_TCHAR *buf, int buflen)
134 ACE_OS_TRACE ("ACE_OS::ctime_r");
136 #if defined (ACE_HAS_REENTRANT_FUNCTIONS)
139 # if defined (ACE_USES_WCHAR)
140 char narrow_buf[ctime_buf_size];
144 # endif /* ACE_USES_WCHAR */
146 if (buflen < ctime_buf_size)
151 # if defined (ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R)
152 # if defined (DIGITAL_UNIX)
153 ACE_OSCALL (::_Pctime_r (t, bufp), ACE_TCHAR *, 0, bufp);
154 # else /* DIGITAL_UNIX */
155 ACE_OSCALL (::ctime_r (t, bufp), char *, 0, bufp);
156 # endif /* DIGITAL_UNIX */
157 # else /* ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R */
159 # if defined (ACE_HAS_SIZET_PTR_ASCTIME_R_AND_CTIME_R)
160 bufp = ::ctime_r (t, bufp, reinterpret_cast<size_t*>(&buflen));
161 # else /* ACE_CTIME_R_RETURNS_INT */
162 bufp = ::ctime_r (t, bufp, buflen);
163 # endif /* ACE_CTIME_R_RETURNS_INT */
165 # endif /* ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R */
170 # if defined (ACE_USES_WCHAR)
171 ACE_Ascii_To_Wide wide_buf (bufp);
172 ACE_OS_String::strcpy (buf, wide_buf.wchar_rep ());
176 # endif /* ACE_USES_WCHAR */
178 #elif defined (ACE_HAS_TR24731_2005_CRT)
179 if (buflen < ctime_buf_size)
184 ACE_TCHAR *result = buf;
185 # if defined (ACE_USES_WCHAR)
186 ACE_SECURECRTCALL (_wctime_s (buf, buflen, t), wchar_t *, 0, result);
188 ACE_SECURECRTCALL (ctime_s (buf, buflen, t), char *, 0, result);
192 #else /* ACE_HAS_REENTRANT_FUNCTIONS */
193 if (buflen < ctime_buf_size)
200 # if defined (ACE_USES_WCHAR)
201 ACE_OSCALL (::_wctime (t), wchar_t *, 0, result);
202 # else /* ACE_USES_WCHAR */
203 ACE_OSCALL (::ctime (t), char *, 0, result);
204 # endif /* ACE_USES_WCHAR */
206 ACE_OS::strsncpy (buf, result, buflen);
208 #endif /* ACE_HAS_REENTRANT_FUNCTIONS */
210 #endif /* !ACE_HAS_WINCE */
212 #if !defined (ACE_LACKS_DIFFTIME)
214 ACE_OS::difftime (time_t t1, time_t t0)
216 return ::ace_difftime (t1, t0);
218 #endif /* ! ACE_LACKS_DIFFTIME */
220 #if defined (ghs) && defined (ACE_HAS_PENTIUM) && !defined (ACE_WIN32)
221 extern "C" ACE_hrtime_t ACE_GETHRTIME_NAME ();
222 #endif /* ghs && ACE_HAS_PENTIUM */
224 ACE_INLINE ACE_hrtime_t
225 ACE_OS::gethrtime (const ACE_HRTimer_Op op)
227 ACE_OS_TRACE ("ACE_OS::gethrtime");
228 #if defined (ACE_HAS_HI_RES_TIMER)
230 return ::gethrtime ();
231 #elif defined (ACE_HAS_AIX_HI_RES_TIMER)
235 ::read_real_time(&tb, TIMEBASE_SZ);
236 ::time_base_to_time(&tb, TIMEBASE_SZ);
238 return ACE_hrtime_t(tb.tb_high) * ACE_ONE_SECOND_IN_NSECS + tb.tb_low;
239 #elif defined (ACE_WIN32)
243 ::QueryPerformanceCounter (&freq);
245 # if defined (ACE_LACKS_LONGLONG_T)
246 ACE_UINT64 uint64_freq (freq.u.LowPart,
247 static_cast<unsigned int> (freq.u.HighPart));
250 return freq.QuadPart;
251 # endif //ACE_LACKS_LONGLONG_T
252 #elif defined (ghs) && defined (ACE_HAS_PENTIUM)
254 // Use .obj/gethrtime.o, which was compiled with g++.
255 return ACE_GETHRTIME_NAME ();
256 #elif (defined (__GNUG__) || defined (__INTEL_COMPILER)) && !defined(ACE_VXWORKS) && defined (ACE_HAS_PENTIUM)
258 # if defined (ACE_LACKS_LONGLONG_T)
260 # else /* ! ACE_LACKS_LONGLONG_T */
262 # endif /* ! ACE_LACKS_LONGLONG_T */
264 #if defined (__amd64__) || defined (__x86_64__)
265 // Read the high res tick counter into 32 bit int variables "eax" and
266 // "edx", and then combine them into 64 bit int "now"
268 asm volatile ("rdtsc" : "=a" (eax), "=d" (edx) : : "memory");
269 now = (((ACE_UINT64) eax) | (((ACE_UINT64) edx) << 32));
271 // Read the high-res tick counter directly into memory variable "now".
272 // The A constraint signifies a 64-bit int.
273 asm volatile ("rdtsc" : "=A" (now) : : "memory");
276 # if defined (ACE_LACKS_LONGLONG_T)
277 ACE_UINT32 least, most;
278 ACE_OS::memcpy (&least, &now, sizeof (ACE_UINT32));
279 ACE_OS::memcpy (&most, (u_char *) &now + sizeof (ACE_UINT32),
280 sizeof (ACE_UINT32));
282 ACE_hrtime_t ret (least, most);
284 # else /* ! ACE_LACKS_LONGLONG_T */
286 # endif /* ! ACE_LACKS_LONGLONG_T */
287 #elif defined (linux) && defined (ACE_HAS_ALPHA_TIMER)
288 // NOTE: alphas only have a 32 bit tick (cycle) counter. The rpcc
289 // instruction actually reads 64 bits, but the high 32 bits are
290 // implementation-specific. Linux and Digital Unix, for example,
291 // use them for virtual tick counts, i.e., taking into account only
292 // the time that the process was running. This information is from
293 // David Mosberger's article, see comment below.
296 // The following statement is based on code published by:
297 // Mosberger, David, "How to Make Your Applications Fly, Part 1",
298 // Linux Journal Issue 42, October 1997, page 50. It reads the
299 // high-res tick counter directly into the memory variable.
300 asm volatile ("rpcc %0" : "=r" (now) : : "memory");
303 #elif defined (ACE_HAS_POWERPC_TIMER) && (defined (ghs) || defined (__GNUG__))
304 // PowerPC w/ GreenHills or g++.
311 ACE_OS::readPPCTimeBase (most, least);
316 asm volatile ("mftbu %0\n"
319 : "=r" (most), "=r" (least), "=r" (scratch));
320 } while (most != scratch);
323 #if defined (ACE_LACKS_LONGLONG_T)
324 return ACE_U_LongLong (least, most);
325 #else /* ! ACE_LACKS_LONGLONG_T */
326 return 0x100000000llu * most + least;
327 #endif /* ! ACE_LACKS_LONGLONG_T */
329 #elif defined (ACE_HAS_CLOCK_GETTIME)
330 // e.g., VxWorks (besides POWERPC && GreenHills) . . .
334 ACE_OS::clock_gettime (
335 #if defined (ACE_HAS_CLOCK_GETTIME_MONOTONIC)
337 #endif /* !ACE_HAS_CLOCK_GETTIME_MONOTONIC */
341 // Carefully create the return value to avoid arithmetic overflow
342 // if ACE_hrtime_t is ACE_U_LongLong.
343 return static_cast<ACE_hrtime_t> (ts.tv_sec) *
344 ACE_U_ONE_SECOND_IN_NSECS + static_cast<ACE_hrtime_t> (ts.tv_nsec);
347 ACE_Time_Value const now = ACE_OS::gettimeofday ();
349 // Carefully create the return value to avoid arithmetic overflow
350 // if ACE_hrtime_t is ACE_U_LongLong.
351 return (static_cast<ACE_hrtime_t> (now.sec ()) * (ACE_UINT32) 1000000 +
352 static_cast<ACE_hrtime_t> (now.usec ())) * (ACE_UINT32) 1000;
353 #endif /* ACE_HAS_HI_RES_TIMER */
356 ACE_INLINE struct tm *
357 ACE_OS::gmtime (const time_t *t)
359 ACE_OS_TRACE ("ACE_OS::gmtime");
360 #if defined (ACE_LACKS_GMTIME)
362 ACE_NOTSUP_RETURN (0);
364 ACE_OSCALL_RETURN (::gmtime (t), struct tm *, 0);
365 #endif /* ACE_LACKS_GMTIME */
368 ACE_INLINE struct tm *
369 ACE_OS::gmtime_r (const time_t *t, struct tm *res)
371 ACE_OS_TRACE ("ACE_OS::gmtime_r");
372 #if defined (ACE_HAS_REENTRANT_FUNCTIONS)
373 # if defined (DIGITAL_UNIX)
374 ACE_OSCALL_RETURN (::_Pgmtime_r (t, res), struct tm *, 0);
376 ACE_OSCALL_RETURN (::gmtime_r (t, res), struct tm *, 0);
377 # endif /* DIGITAL_UNIX */
378 #elif defined (ACE_HAS_TR24731_2005_CRT)
379 struct tm *tm_p = res;
380 ACE_SECURECRTCALL (gmtime_s (res, t), struct tm *, 0, tm_p);
382 #elif defined (ACE_LACKS_GMTIME_R)
384 ACE_UNUSED_ARG (res);
385 ACE_NOTSUP_RETURN (0);
388 ACE_OSCALL (::gmtime (t), struct tm *, 0, result) ;
392 #endif /* ACE_HAS_REENTRANT_FUNCTIONS */
395 ACE_INLINE struct tm *
396 ACE_OS::localtime (const time_t *t)
398 ACE_OS_TRACE ("ACE_OS::localtime");
399 #if defined (ACE_LACKS_LOCALTIME)
401 ACE_NOTSUP_RETURN (0);
403 ACE_OSCALL_RETURN (::localtime (t), struct tm *, 0);
404 #endif /* ACE_LACKS_LOCALTIME */
408 ACE_OS::nanosleep (const struct timespec *requested,
409 struct timespec *remaining)
411 ACE_OS_TRACE ("ACE_OS::nanosleep");
412 #if defined (ACE_HAS_CLOCK_GETTIME)
413 // ::nanosleep () is POSIX 1003.1b. So is ::clock_gettime (). So,
414 // if ACE_HAS_CLOCK_GETTIME is defined, then ::nanosleep () should
415 // be available on the platform. On Solaris 2.x, both functions
416 // require linking with -lposix4.
417 return ::nanosleep ((ACE_TIMESPEC_PTR) requested, remaining);
419 ACE_UNUSED_ARG (remaining);
421 // Convert into seconds and microseconds.
422 ACE_Time_Value tv (requested->tv_sec,
423 requested->tv_nsec / 1000);
424 return ACE_OS::sleep (tv);
425 #endif /* ACE_HAS_CLOCK_GETTIME */
429 ACE_OS::strftime (char *s, size_t maxsize, const char *format,
430 const struct tm *timeptr)
432 #if defined (ACE_LACKS_STRFTIME)
434 ACE_UNUSED_ARG (maxsize);
435 ACE_UNUSED_ARG (format);
436 ACE_UNUSED_ARG (timeptr);
437 ACE_NOTSUP_RETURN (0);
439 return ACE_STD_NAMESPACE::strftime (s, maxsize, format, timeptr);
440 #endif /* ACE_LACKS_STRFTIME */
444 ACE_OS::strptime (const char *buf, const char *format, struct tm *tm)
446 #if defined (ACE_LACKS_STRPTIME)
447 # if defined (ACE_REFUSE_STRPTIME_EMULATION)
448 ACE_UNUSED_ARG (buf);
449 ACE_UNUSED_ARG (format);
451 ACE_NOTSUP_RETURN (0);
453 return ACE_OS::strptime_emulation (buf, format, tm);
454 # endif /* ACE_REFUSE_STRPTIME_EMULATION */
456 return ::strptime (buf, format, tm);
457 #endif /* ACE_LACKS_STRPTIME */
461 ACE_OS::time (time_t *tloc)
463 ACE_OS_TRACE ("ACE_OS::time");
464 #if !defined (ACE_HAS_WINCE)
465 ACE_OSCALL_RETURN (::time (tloc), time_t, (time_t) -1);
467 time_t retv = ACE_OS::gettimeofday ().sec ();
471 #endif /* ACE_HAS_WINCE */
474 // Linux won't compile unless we explicitly use a namespace here.
475 #if defined (__GNUG__)
480 return ::ace_timezone ();
482 } /* namespace ACE_OS */
485 ACE_OS::timezone (void)
487 return ::ace_timezone ();
494 #if !defined (ACE_HAS_WINCE) && !defined (ACE_VXWORKS) && !defined(ACE_HAS_RTEMS) && !defined (ACE_HAS_DINKUM_STL)
495 # if defined (ACE_WIN32)
496 ::_tzset (); // For Win32.
498 ::tzset (); // For UNIX platforms.
499 # endif /* ACE_WIN32 */
502 # endif /* ACE_HAS_WINCE && !VXWORKS && !ACE_HAS_RTEMS && !ACE_HAS_DINKUM_STL */
505 ACE_END_VERSIONED_NAMESPACE_DECL