Also use Objects as part of an operation but as a result don't generate Any operation...
[ACE_TAO.git] / ACE / ace / OS_NS_time.inl
blob6bd482761eab9b58bf5d427728cb91fb54f00bd0
1 // -*- C++ -*-
2 #include "ace/OS_NS_string.h"
3 #include "ace/OS_NS_errno.h"
4 #include "ace/Time_Value.h"
5 #include "ace/OS_NS_unistd.h"
6 #include "ace/OS_NS_sys_time.h"
8 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
10 ACE_INLINE char *
11 ACE_OS::asctime (const struct tm *t)
13   ACE_OS_TRACE ("ACE_OS::asctime");
14 #if defined (ACE_LACKS_ASCTIME)
15   ACE_UNUSED_ARG (t);
16   ACE_NOTSUP_RETURN (0);
17 #else
18   ACE_OSCALL_RETURN (ACE_STD_NAMESPACE::asctime (t), char *, 0);
19 #endif /* ACE_LACKS_ASCTIME */
22 ACE_INLINE char *
23 ACE_OS::asctime_r (const struct tm *t, char *buf, int buflen)
25   ACE_OS_TRACE ("ACE_OS::asctime_r");
26 #if defined (ACE_HAS_REENTRANT_FUNCTIONS)
27 # if defined (ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R)
28   char *result = 0;
29   ace_asctime_r_helper (t, buf);
30   ACE_OS::strsncpy (buf, result, buflen);
31   return buf;
32 # else
33 #   if defined (ACE_HAS_SIZET_PTR_ASCTIME_R_AND_CTIME_R)
34   ACE_OSCALL_RETURN (::asctime_r (t, buf, reinterpret_cast<size_t*>(&buflen)), char *, 0);
35 #   else
36   ACE_OSCALL_RETURN (::asctime_r (t, buf, buflen), char *, 0);
37 #   endif /* ACE_HAS_SIZET_PTR_ASCTIME_R_AND_CTIME_R */
38 # endif /* ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R */
39 #elif defined (ACE_HAS_TR24731_2005_CRT)
40   char *result = buf;
41   ACE_SECURECRTCALL (asctime_s (buf, static_cast<size_t> (buflen), t), \
42                      char*, 0, result);
43   return result;
44 #elif defined (ACE_LACKS_ASCTIME)
45   ACE_UNUSED_ARG (t);
46   ACE_UNUSED_ARG (buf);
47   ACE_UNUSED_ARG (buflen);
48   ACE_NOTSUP_RETURN (0);
49 #else
50   char *result = 0;
51   ACE_OSCALL (ACE_STD_NAMESPACE::asctime (t), char *, 0, result);
52   ACE_OS::strsncpy (buf, result, buflen);
53   return buf;
54 #endif /* ACE_HAS_REENTRANT_FUNCTIONS */
57 ACE_INLINE int
58 ACE_OS::clock_gettime (clockid_t clockid, struct timespec *ts)
60   ACE_OS_TRACE ("ACE_OS::clock_gettime");
61 #if defined (ACE_HAS_CLOCK_GETTIME)
62   ACE_OSCALL_RETURN (::clock_gettime (clockid, ts), int, -1);
63 #else
64   ACE_UNUSED_ARG (clockid);
65   ACE_UNUSED_ARG (ts);
66   ACE_NOTSUP_RETURN (-1);
67 #endif /* ACE_HAS_CLOCK_GETTIME */
70 ACE_INLINE int
71 ACE_OS::clock_settime (clockid_t clockid, const struct timespec *ts)
73 #if defined (ACE_HAS_CLOCK_SETTIME)
74 #  if defined (ACE_HAS_NONCONST_CLOCK_SETTIME)
75   ACE_OSCALL_RETURN (::clock_settime (clockid, const_cast<struct timespec *>(ts)), int, -1);
76 #  else
77   ACE_OSCALL_RETURN (::clock_settime (clockid, ts), int, -1);
78 #  endif /* ACE_HAS_NONCONST_CLOCK_SETTIME */
79 #else
80   ACE_UNUSED_ARG (clockid);
81   ACE_UNUSED_ARG (ts);
82   ACE_NOTSUP_RETURN (-1);
83 #endif /* ACE_HAS_CLOCK_SETTIME */
86 // Magic number declaration and definition for ctime and ctime_r ()
87 static const int ctime_buf_size = 26;
89 ACE_INLINE ACE_TCHAR *
90 ACE_OS::ctime (const time_t *t)
92   ACE_OS_TRACE ("ACE_OS::ctime");
93 #if defined (ACE_LACKS_CTIME)
94   ACE_UNUSED_ARG (t);
95   ACE_NOTSUP_RETURN (0);
96 #elif defined (ACE_HAS_WINCE)
97   static ACE_TCHAR buf [ctime_buf_size];
98   return ACE_OS::ctime_r (t,
99                           buf,
100                           ctime_buf_size);
101 #elif defined (ACE_WIN32) && defined (ACE_USES_WCHAR)
102   ACE_OSCALL_RETURN (::_wctime (t), wchar_t *, 0);
103 #else
104 #  if defined (ACE_USES_WCHAR)   /* Not Win32, else it would do the above */
105   char *narrow_time;
106   ACE_OSCALL (::ctime (t), char *, 0, narrow_time);
107   if (narrow_time == 0)
108     return 0;
109   // ACE_Ascii_To_Wide::convert allocates (via new []) a wchar_t[]. If
110   // we've done this before, free the previous one. Yes, this leaves a
111   // small memory leak (26 characters) but there's no way around this
112   // that I know of. (Steve Huston, 12-Feb-2003).
113   static wchar_t *wide_time = 0;
114   if (wide_time != 0)
115     delete [] wide_time;
116   wide_time = ACE_Ascii_To_Wide::convert (narrow_time);
117   return wide_time;
118 #  else
119   ACE_OSCALL_RETURN (::ctime (t), char *, 0);
120 #  endif /* ACE_USES_WCHAR */
121 # endif /* ACE_HAS_WINCE */
124 #if !defined (ACE_HAS_WINCE)  /* CE version in OS.cpp */
125 ACE_INLINE ACE_TCHAR *
126 ACE_OS::ctime_r (const time_t *t, ACE_TCHAR *buf, int buflen)
128   ACE_OS_TRACE ("ACE_OS::ctime_r");
130 #if defined (ACE_HAS_REENTRANT_FUNCTIONS)
132   char *bufp = 0;
133 #   if defined (ACE_USES_WCHAR)
134   char narrow_buf[ctime_buf_size];
135   bufp = narrow_buf;
136 #   else
137   bufp = buf;
138 #   endif /* ACE_USES_WCHAR */
140   if (buflen < ctime_buf_size)
141     {
142       errno = ERANGE;
143       return 0;
144     }
145 #   if defined (ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R)
146   ACE_OSCALL (::ctime_r (t, bufp), char *, 0, bufp);
147 #   else /* ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R */
149 #      if defined (ACE_HAS_SIZET_PTR_ASCTIME_R_AND_CTIME_R)
150   bufp = ::ctime_r (t, bufp, reinterpret_cast<size_t*>(&buflen));
151 #      else /* ACE_CTIME_R_RETURNS_INT */
152   bufp = ::ctime_r (t, bufp, buflen);
153 #      endif /* ACE_CTIME_R_RETURNS_INT */
155 #   endif /* ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R */
157   if (bufp == 0)
158     return 0;
160 #   if defined (ACE_USES_WCHAR)
161   ACE_Ascii_To_Wide wide_buf (bufp);
162   ACE_OS::strcpy (buf, wide_buf.wchar_rep ());
163   return buf;
164 #   else
165   return bufp;
166 #   endif /* ACE_USES_WCHAR */
168 #elif defined (ACE_HAS_TR24731_2005_CRT)
169   if (buflen < ctime_buf_size)
170     {
171       errno = ERANGE;
172       return 0;
173     }
174   ACE_TCHAR *result = buf;
175 #  if defined (ACE_USES_WCHAR)
176   ACE_SECURECRTCALL (_wctime_s (buf, buflen, t), wchar_t *, 0, result);
177 #  else
178   ACE_SECURECRTCALL (ctime_s (buf, buflen, t), char *, 0, result);
179 #  endif
180   return result;
182 #else /* ACE_HAS_REENTRANT_FUNCTIONS */
183   if (buflen < ctime_buf_size)
184     {
185       errno = ERANGE;
186       return 0;
187     }
189   ACE_TCHAR *result = 0;
190 #     if defined (ACE_USES_WCHAR)
191   ACE_OSCALL (::_wctime (t), wchar_t *, 0, result);
192 #     else /* ACE_USES_WCHAR */
193   ACE_OSCALL (::ctime (t), char *, 0, result);
194 #     endif /* ACE_USES_WCHAR */
195   if (result != 0)
196     ACE_OS::strsncpy (buf, result, buflen);
197   return buf;
198 #endif /* ACE_HAS_REENTRANT_FUNCTIONS */
200 #endif /* !ACE_HAS_WINCE */
202 #if defined (ACE_USES_ULONG_FOR_STAT_TIME)
203 ACE_INLINE ACE_TCHAR *
204 ACE_OS::ctime (const unsigned long *t)
206   return ACE_OS::ctime (reinterpret_cast<const time_t *>(t));
209 ACE_INLINE ACE_TCHAR *
210 ACE_OS::ctime_r (const unsigned long *clock, ACE_TCHAR *buf, int buflen)
212   return ACE_OS::ctime_r (reinterpret_cast<const time_t *>(clock), buf, buflen);
215 ACE_INLINE struct tm *
216 ACE_OS::gmtime (const unsigned long *clock)
218   return ACE_OS::gmtime (reinterpret_cast<const time_t *>(clock));
221 ACE_INLINE struct tm *
222 ACE_OS::gmtime_r (const unsigned long *clock,
223                   struct tm *res)
225   return ACE_OS::gmtime_r (reinterpret_cast<const time_t *>(clock), res);
228 ACE_INLINE struct tm *
229 ACE_OS::localtime (const unsigned long *clock)
231   return ACE_OS::localtime (reinterpret_cast<const time_t *>(clock));
234 ACE_INLINE struct tm *
235 ACE_OS::localtime_r (const unsigned long *clock,
236                      struct tm *res)
238   return ACE_OS::localtime_r (reinterpret_cast<const time_t *>(clock), res);
242 #endif
244 #if !defined (ACE_LACKS_DIFFTIME)
245 ACE_INLINE double
246 ACE_OS::difftime (time_t t1, time_t t0)
248   return ::ace_difftime (t1, t0);
250 #endif /* ! ACE_LACKS_DIFFTIME */
252 ACE_INLINE ACE_hrtime_t
253 ACE_OS::gethrtime (const ACE_HRTimer_Op op)
255   ACE_OS_TRACE ("ACE_OS::gethrtime");
256 #if defined (ACE_HAS_HI_RES_TIMER)
257   ACE_UNUSED_ARG (op);
258   return ::gethrtime ();
259 #elif defined (ACE_HAS_AIX_HI_RES_TIMER)
260   ACE_UNUSED_ARG (op);
261   timebasestruct_t tb;
263   ::read_real_time(&tb, TIMEBASE_SZ);
264   ::time_base_to_time(&tb, TIMEBASE_SZ);
266   return ACE_hrtime_t(tb.tb_high) * ACE_ONE_SECOND_IN_NSECS + tb.tb_low;
267 #elif defined (ACE_WIN32)
268   ACE_UNUSED_ARG(op);
269   LARGE_INTEGER freq;
271   ::QueryPerformanceCounter (&freq);
273   return freq.QuadPart;
274 #elif defined (ghs) && defined (ACE_HAS_PENTIUM)
275   ACE_UNUSED_ARG (op);
276   // Use .obj/gethrtime.o, which was compiled with g++.
277   return ACE_GETHRTIME_NAME ();
278 #elif (defined (__GNUG__) || defined (__INTEL_COMPILER)) && \
279   !defined (ACE_VXWORKS) && defined (ACE_HAS_PENTIUM) && \
280   !defined (ACE_LACKS_PENTIUM_RDTSC)
281   ACE_UNUSED_ARG (op);
282   ACE_hrtime_t now;
284 # if defined (__amd64__) || defined (__x86_64__)
285   // Read the high res tick counter into 32 bit int variables "eax" and
286   // "edx", and then combine them into 64 bit int "now"
287   ACE_UINT32 eax, edx;
288   asm volatile ("rdtsc" : "=a" (eax), "=d" (edx) : : "memory");
289   now = (((ACE_UINT64) eax) | (((ACE_UINT64) edx) << 32));
290 # else
291   // Read the high-res tick counter directly into memory variable "now".
292   // The A constraint signifies a 64-bit int.
293   asm volatile ("rdtsc" : "=A" (now) : : "memory");
294 # endif
296   return now;
297 #elif defined (ACE_LINUX) && defined (ACE_HAS_ALPHA_TIMER)
298   // NOTE:  alphas only have a 32 bit tick (cycle) counter.  The rpcc
299   // instruction actually reads 64 bits, but the high 32 bits are
300   // implementation-specific.  Linux and Digital Unix, for example,
301   // use them for virtual tick counts, i.e., taking into account only
302   // the time that the process was running.  This information is from
303   // David Mosberger's article, see comment below.
304   ACE_UINT32 now;
306   // The following statement is based on code published by:
307   // Mosberger, David, "How to Make Your Applications Fly, Part 1",
308   // Linux Journal Issue 42, October 1997, page 50.  It reads the
309   // high-res tick counter directly into the memory variable.
310   asm volatile ("rpcc %0" : "=r" (now) : : "memory");
312   return now;
313 #elif defined (ACE_HAS_POWERPC_TIMER) && (defined (ghs) || defined (__GNUG__))
314   // PowerPC w/ GreenHills or g++.
316   ACE_UNUSED_ARG (op);
317   u_long most;
318   u_long least;
320 #  if defined (ghs)
321   ACE_OS::readPPCTimeBase (most, least);
322 #  else
323   u_long scratch;
325   do {
326     asm volatile ("mftbu %0\n"
327           "mftb  %1\n"
328           "mftbu %2"
329           : "=r" (most), "=r" (least), "=r" (scratch));
330   } while (most != scratch);
331 #  endif
333   return 0x100000000llu * most  +  least;
335 #elif defined (ACE_HAS_CLOCK_GETTIME)
336   // e.g., VxWorks (besides POWERPC && GreenHills) . . .
337   ACE_UNUSED_ARG (op);
338   struct timespec ts;
340   ACE_OS::clock_gettime (
341 #  if defined (ACE_HAS_CLOCK_GETTIME_MONOTONIC)
342          CLOCK_MONOTONIC,
343 #  else
344          CLOCK_REALTIME,
345 #  endif /* !ACE_HAS_CLOCK_GETTIME_MONOTONIC */
346          &ts);
348   // Carefully create the return value to avoid arithmetic overflow
349   return static_cast<ACE_hrtime_t> (ts.tv_sec) *
350     ACE_U_ONE_SECOND_IN_NSECS  +  static_cast<ACE_hrtime_t> (ts.tv_nsec);
351 #else
352   ACE_UNUSED_ARG (op);
353   ACE_Time_Value const now = ACE_OS::gettimeofday ();
355   // Carefully create the return value to avoid arithmetic overflow
356   return (static_cast<ACE_hrtime_t> (now.sec ()) * (ACE_UINT32) 1000000  +
357           static_cast<ACE_hrtime_t> (now.usec ())) * (ACE_UINT32) 1000;
358 #endif /* ACE_HAS_HI_RES_TIMER */
361 ACE_INLINE struct tm *
362 ACE_OS::gmtime (const time_t *t)
364   ACE_OS_TRACE ("ACE_OS::gmtime");
365 #if defined (ACE_LACKS_GMTIME)
366   ACE_UNUSED_ARG (t);
367   ACE_NOTSUP_RETURN (0);
368 #else
369   ACE_OSCALL_RETURN (::gmtime (t), struct tm *, 0);
370 #endif /* ACE_LACKS_GMTIME */
373 ACE_INLINE struct tm *
374 ACE_OS::gmtime_r (const time_t *t, struct tm *res)
376   ACE_OS_TRACE ("ACE_OS::gmtime_r");
377 #if defined (ACE_HAS_REENTRANT_FUNCTIONS)
378   return ace_gmtime_r_helper (t, res);
379 #elif defined (ACE_HAS_TR24731_2005_CRT)
380   struct tm *tm_p = res;
381   ACE_SECURECRTCALL (gmtime_s (res, t), struct tm *, 0, tm_p);
382   return tm_p;
383 #elif defined (ACE_LACKS_GMTIME)
384   ACE_UNUSED_ARG (t);
385   ACE_UNUSED_ARG (res);
386   ACE_NOTSUP_RETURN (0);
387 #else
388   struct tm *result;
389   ACE_OSCALL (::gmtime (t), struct tm *, 0, result) ;
390   if (result != 0)
391     *res = *result;
392   return res;
393 #endif /* ACE_HAS_REENTRANT_FUNCTIONS */
396 ACE_INLINE struct tm *
397 ACE_OS::localtime (const time_t *t)
399   ACE_OS_TRACE ("ACE_OS::localtime");
400 #if defined (ACE_LACKS_LOCALTIME)
401   ACE_UNUSED_ARG (t);
402   ACE_NOTSUP_RETURN (0);
403 #else
404   ACE_OSCALL_RETURN (::localtime (t), struct tm *, 0);
405 #endif /* ACE_LACKS_LOCALTIME */
408 ACE_INLINE int
409 ACE_OS::nanosleep (const struct timespec *requested,
410                    struct timespec *remaining)
412   ACE_OS_TRACE ("ACE_OS::nanosleep");
413 #if defined (ACE_HAS_CLOCK_GETTIME)
414   // ::nanosleep () is POSIX 1003.1b.  So is ::clock_gettime ().  So,
415   // if ACE_HAS_CLOCK_GETTIME is defined, then ::nanosleep () should
416   // be available on the platform.  On Solaris 2.x, both functions
417   // require linking with -lposix4.
418   return ::nanosleep ((ACE_TIMESPEC_PTR) requested, remaining);
419 #else
420   ACE_UNUSED_ARG (remaining);
422   // Convert into seconds and microseconds.
423   ACE_Time_Value tv (requested->tv_sec,
424                      requested->tv_nsec / 1000);
425   return ACE_OS::sleep (tv);
426 #endif /* ACE_HAS_CLOCK_GETTIME */
429 ACE_INLINE size_t
430 ACE_OS::strftime (char *s, size_t maxsize, const char *format,
431                   const struct tm *timeptr)
433 #if defined (ACE_LACKS_STRFTIME)
434   ACE_UNUSED_ARG (s);
435   ACE_UNUSED_ARG (maxsize);
436   ACE_UNUSED_ARG (format);
437   ACE_UNUSED_ARG (timeptr);
438   ACE_NOTSUP_RETURN (0);
439 #else
440   return ACE_STD_NAMESPACE::strftime (s, maxsize, format, timeptr);
441 #endif /* ACE_LACKS_STRFTIME */
444 ACE_INLINE char *
445 ACE_OS::strptime (const char *buf, const char *format, struct tm *tm)
447   ACE_OS::memset (tm, 0, sizeof (struct tm));
448 #if defined (ACE_LACKS_STRPTIME)
449   return ACE_OS::strptime_emulation (buf, format, tm);
450 #else
451   return ACE_STD_NAMESPACE::strptime (buf, format, tm);
452 #endif /* ACE_LACKS_STRPTIME */
455 ACE_INLINE time_t
456 ACE_OS::time (time_t *tloc)
458   ACE_OS_TRACE ("ACE_OS::time");
459 #if defined (ACE_LACKS_TIME)
460   time_t const retv = ACE_OS::gettimeofday ().sec ();
461   if (tloc)
462     *tloc = retv;
463   return retv;
464 #else
465   ACE_OSCALL_RETURN (::time (tloc), time_t, (time_t) -1);
466 #endif /* ACE_LACKS_TIME */
469 // Linux won't compile unless we explicitly use a namespace here.
470 #if defined (__GNUG__)
471 namespace ACE_OS {
472   ACE_INLINE long
473   timezone (void)
474   {
475     return ::ace_timezone ();
476   }
477 } /* namespace ACE_OS */
478 #else
479 ACE_INLINE long
480 ACE_OS::timezone (void)
482   return ::ace_timezone ();
484 #endif /* ACE_LINUX */
486 ACE_INLINE void
487 ACE_OS::tzset (void)
489 #if defined (ACE_LACKS_TZSET)
490   errno = ENOTSUP;
491 #elif defined (ACE_WIN32)
492   ::_tzset ();  // For Win32.
493 #else
494   ::tzset ();   // For UNIX platforms.
495 #endif /* ACE_LACKS_TZSET */
498 ACE_END_VERSIONED_NAMESPACE_DECL