Document return values
[ACE_TAO.git] / ACE / ace / OS_NS_time.inl
bloba41b805d4d0da2752d5c85f909140c88af3ed74c
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"
7 #include <ctime>
9 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
11 ACE_INLINE char *
12 ACE_OS::asctime (const struct tm *t)
14   ACE_OS_TRACE ("ACE_OS::asctime");
15 #if defined (ACE_LACKS_ASCTIME)
16   ACE_UNUSED_ARG (t);
17   ACE_NOTSUP_RETURN (0);
18 #else
19   return std::asctime (t);
20 #endif /* ACE_LACKS_ASCTIME */
23 ACE_INLINE char *
24 ACE_OS::asctime_r (const struct tm *t, char *buf, int buflen)
26   ACE_OS_TRACE ("ACE_OS::asctime_r");
27 #if defined (ACE_HAS_REENTRANT_FUNCTIONS)
28 # if defined (ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R)
29   char *result = 0;
30   ace_asctime_r_helper (t, buf);
31   ACE_OS::strsncpy (buf, result, buflen);
32   return buf;
33 # else
34 #   if defined (ACE_HAS_SIZET_PTR_ASCTIME_R_AND_CTIME_R)
35   return ::asctime_r (t, buf, reinterpret_cast<size_t*>(&buflen));
36 #   else
37   return ::asctime_r (t, buf, buflen);
38 #   endif /* ACE_HAS_SIZET_PTR_ASCTIME_R_AND_CTIME_R */
39 # endif /* ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R */
40 #elif defined (ACE_HAS_TR24731_2005_CRT)
41   char *result = buf;
42   ACE_SECURECRTCALL (asctime_s (buf, static_cast<size_t> (buflen), t), \
43                      char*, 0, result);
44   return result;
45 #elif defined (ACE_LACKS_ASCTIME)
46   ACE_UNUSED_ARG (t);
47   ACE_UNUSED_ARG (buf);
48   ACE_UNUSED_ARG (buflen);
49   ACE_NOTSUP_RETURN (0);
50 #else
51   char *result = 0;
52   ACE_OSCALL (std::asctime (t), char *, result);
53   ACE_OS::strsncpy (buf, result, buflen);
54   return buf;
55 #endif /* ACE_HAS_REENTRANT_FUNCTIONS */
58 ACE_INLINE int
59 ACE_OS::clock_gettime (clockid_t clockid, struct timespec *ts)
61   ACE_OS_TRACE ("ACE_OS::clock_gettime");
62 #if defined (ACE_HAS_CLOCK_GETTIME)
63   return ::clock_gettime (clockid, ts);
64 #else
65   ACE_UNUSED_ARG (clockid);
66   ACE_UNUSED_ARG (ts);
67   ACE_NOTSUP_RETURN (-1);
68 #endif /* ACE_HAS_CLOCK_GETTIME */
71 ACE_INLINE int
72 ACE_OS::clock_settime (clockid_t clockid, const struct timespec *ts)
74 #if defined (ACE_HAS_CLOCK_SETTIME)
75 #  if defined (ACE_HAS_NONCONST_CLOCK_SETTIME)
76   return ::clock_settime (clockid, const_cast<struct timespec *>(ts));
77 #  else
78   return ::clock_settime (clockid, ts);
79 #  endif /* ACE_HAS_NONCONST_CLOCK_SETTIME */
80 #else
81   ACE_UNUSED_ARG (clockid);
82   ACE_UNUSED_ARG (ts);
83   ACE_NOTSUP_RETURN (-1);
84 #endif /* ACE_HAS_CLOCK_SETTIME */
87 // Magic number declaration and definition for ctime and ctime_r ()
88 static constexpr int ctime_buf_size = 26;
90 ACE_INLINE ACE_TCHAR *
91 ACE_OS::ctime (const time_t *t)
93   ACE_OS_TRACE ("ACE_OS::ctime");
94 #if defined (ACE_LACKS_CTIME)
95   ACE_UNUSED_ARG (t);
96   ACE_NOTSUP_RETURN (0);
97 #elif defined (ACE_WIN32) && defined (ACE_USES_WCHAR)
98   return ::_wctime (t);
99 #else
100 #  if defined (ACE_USES_WCHAR)   /* Not Win32, else it would do the above */
101   char *narrow_time;
102   ACE_OSCALL (::ctime (t), char *, narrow_time);
103   if (narrow_time == 0)
104     return 0;
105   // ACE_Ascii_To_Wide::convert allocates (via new []) a wchar_t[]. If
106   // we've done this before, free the previous one. Yes, this leaves a
107   // small memory leak (26 characters) but there's no way around this
108   // that I know of. (Steve Huston, 12-Feb-2003).
109   static wchar_t *wide_time = 0;
110   if (wide_time != 0)
111     delete [] wide_time;
112   wide_time = ACE_Ascii_To_Wide::convert (narrow_time);
113   return wide_time;
114 #  else
115   return ::ctime (t);
116 #  endif /* ACE_USES_WCHAR */
117 # endif /* ACE_LACKS_CTIME */
120 ACE_INLINE ACE_TCHAR *
121 ACE_OS::ctime_r (const time_t *t, ACE_TCHAR *buf, int buflen)
123   ACE_OS_TRACE ("ACE_OS::ctime_r");
125 #if defined (ACE_HAS_REENTRANT_FUNCTIONS)
127   char *bufp = 0;
128 #   if defined (ACE_USES_WCHAR)
129   char narrow_buf[ctime_buf_size];
130   bufp = narrow_buf;
131 #   else
132   bufp = buf;
133 #   endif /* ACE_USES_WCHAR */
135   if (buflen < ctime_buf_size)
136     {
137       errno = ERANGE;
138       return 0;
139     }
140 #   if defined (ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R)
141   ACE_OSCALL (::ctime_r (t, bufp), char *, bufp);
142 #   else /* ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R */
144 #      if defined (ACE_HAS_SIZET_PTR_ASCTIME_R_AND_CTIME_R)
145   bufp = ::ctime_r (t, bufp, reinterpret_cast<size_t*>(&buflen));
146 #      else /* ACE_CTIME_R_RETURNS_INT */
147   bufp = ::ctime_r (t, bufp, buflen);
148 #      endif /* ACE_CTIME_R_RETURNS_INT */
150 #   endif /* ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R */
152   if (bufp == 0)
153     return 0;
155 #   if defined (ACE_USES_WCHAR)
156   ACE_Ascii_To_Wide wide_buf (bufp);
157   ACE_OS::strcpy (buf, wide_buf.wchar_rep ());
158   return buf;
159 #   else
160   return bufp;
161 #   endif /* ACE_USES_WCHAR */
163 #elif defined (ACE_HAS_TR24731_2005_CRT)
164   if (buflen < ctime_buf_size)
165     {
166       errno = ERANGE;
167       return 0;
168     }
169   ACE_TCHAR *result = buf;
170 #  if defined (ACE_USES_WCHAR)
171   ACE_SECURECRTCALL (_wctime_s (buf, buflen, t), wchar_t *, 0, result);
172 #  else
173   ACE_SECURECRTCALL (ctime_s (buf, buflen, t), char *, 0, result);
174 #  endif
175   return result;
177 #else /* ACE_HAS_REENTRANT_FUNCTIONS */
178   if (buflen < ctime_buf_size)
179     {
180       errno = ERANGE;
181       return 0;
182     }
184   ACE_TCHAR *result = 0;
185 #     if defined (ACE_USES_WCHAR)
186   ACE_OSCALL (::_wctime (t), wchar_t *, result);
187 #     else /* ACE_USES_WCHAR */
188   ACE_OSCALL (::ctime (t), char *, result);
189 #     endif /* ACE_USES_WCHAR */
190   if (result != 0)
191     ACE_OS::strsncpy (buf, result, buflen);
192   return buf;
193 #endif /* ACE_HAS_REENTRANT_FUNCTIONS */
196 #if defined (ACE_USES_ULONG_FOR_STAT_TIME)
197 ACE_INLINE ACE_TCHAR *
198 ACE_OS::ctime (const unsigned long *t)
200   return ACE_OS::ctime (reinterpret_cast<const time_t *>(t));
203 ACE_INLINE ACE_TCHAR *
204 ACE_OS::ctime_r (const unsigned long *clock, ACE_TCHAR *buf, int buflen)
206   return ACE_OS::ctime_r (reinterpret_cast<const time_t *>(clock), buf, buflen);
209 ACE_INLINE struct tm *
210 ACE_OS::gmtime (const unsigned long *clock)
212   return ACE_OS::gmtime (reinterpret_cast<const time_t *>(clock));
215 ACE_INLINE struct tm *
216 ACE_OS::gmtime_r (const unsigned long *clock,
217                   struct tm *res)
219   return ACE_OS::gmtime_r (reinterpret_cast<const time_t *>(clock), res);
222 ACE_INLINE struct tm *
223 ACE_OS::localtime (const unsigned long *clock)
225   return ACE_OS::localtime (reinterpret_cast<const time_t *>(clock));
228 ACE_INLINE struct tm *
229 ACE_OS::localtime_r (const unsigned long *clock,
230                      struct tm *res)
232   return ACE_OS::localtime_r (reinterpret_cast<const time_t *>(clock), res);
236 #endif
238 ACE_INLINE double
239 ACE_OS::difftime (time_t t1, time_t t0)
241   return ::ace_difftime (t1, t0);
244 ACE_INLINE ACE_hrtime_t
245 ACE_OS::gethrtime (const ACE_HRTimer_Op op)
247   ACE_OS_TRACE ("ACE_OS::gethrtime");
248 #if defined (ACE_HAS_HI_RES_TIMER)
249   ACE_UNUSED_ARG (op);
250   return ::gethrtime ();
251 #elif defined (ACE_WIN32)
252   ACE_UNUSED_ARG(op);
253   LARGE_INTEGER freq;
255   ::QueryPerformanceCounter (&freq);
257   return freq.QuadPart;
258 #elif defined (ghs) && defined (ACE_HAS_PENTIUM)
259   ACE_UNUSED_ARG (op);
260   // Use .obj/gethrtime.o, which was compiled with g++.
261   return ACE_GETHRTIME_NAME ();
262 #elif (defined (__GNUG__) || defined (__INTEL_COMPILER)) && \
263   !defined (ACE_VXWORKS) && defined (ACE_HAS_PENTIUM) && \
264   !defined (ACE_LACKS_PENTIUM_RDTSC)
265   ACE_UNUSED_ARG (op);
266   ACE_hrtime_t now;
268 # if defined (__amd64__) || defined (__x86_64__)
269   // Read the high res tick counter into 32 bit int variables "eax" and
270   // "edx", and then combine them into 64 bit int "now"
271   ACE_UINT32 eax, edx;
272   asm volatile ("rdtsc" : "=a" (eax), "=d" (edx) : : "memory");
273   now = (((ACE_UINT64) eax) | (((ACE_UINT64) edx) << 32));
274 # else
275   // Read the high-res tick counter directly into memory variable "now".
276   // The A constraint signifies a 64-bit int.
277   asm volatile ("rdtsc" : "=A" (now) : : "memory");
278 # endif
280   return now;
281 #elif defined (ACE_HAS_POWERPC_TIMER) && (defined (ghs) || defined (__GNUG__))
282   // PowerPC w/ GreenHills or g++.
284   ACE_UNUSED_ARG (op);
285   u_long most;
286   u_long least;
288 #  if defined (ghs)
289   ACE_OS::readPPCTimeBase (most, least);
290 #  else
291   u_long scratch;
293   do {
294     asm volatile ("mftbu %0\n"
295           "mftb  %1\n"
296           "mftbu %2"
297           : "=r" (most), "=r" (least), "=r" (scratch));
298   } while (most != scratch);
299 #  endif
301   return 0x100000000llu * most  +  least;
303 #elif defined (ACE_HAS_CLOCK_GETTIME)
304   // e.g., VxWorks (besides POWERPC && GreenHills) . . .
305   ACE_UNUSED_ARG (op);
306   struct timespec ts;
308   ACE_OS::clock_gettime (
309 #  if defined (ACE_HAS_CLOCK_GETTIME_MONOTONIC)
310          CLOCK_MONOTONIC,
311 #  else
312          CLOCK_REALTIME,
313 #  endif /* !ACE_HAS_CLOCK_GETTIME_MONOTONIC */
314          &ts);
316   // Carefully create the return value to avoid arithmetic overflow
317   return static_cast<ACE_hrtime_t> (ts.tv_sec) *
318     ACE_U_ONE_SECOND_IN_NSECS  +  static_cast<ACE_hrtime_t> (ts.tv_nsec);
319 #else
320   ACE_UNUSED_ARG (op);
321   ACE_Time_Value const now = ACE_OS::gettimeofday ();
323   // Carefully create the return value to avoid arithmetic overflow
324   return (static_cast<ACE_hrtime_t> (now.sec ()) * (ACE_UINT32) 1000000  +
325           static_cast<ACE_hrtime_t> (now.usec ())) * (ACE_UINT32) 1000;
326 #endif /* ACE_HAS_HI_RES_TIMER */
329 ACE_INLINE struct tm *
330 ACE_OS::gmtime (const time_t *t)
332   ACE_OS_TRACE ("ACE_OS::gmtime");
333 #if defined (ACE_LACKS_GMTIME)
334   ACE_UNUSED_ARG (t);
335   ACE_NOTSUP_RETURN (0);
336 #else
337   return ::gmtime (t);
338 #endif /* ACE_LACKS_GMTIME */
341 ACE_INLINE struct tm *
342 ACE_OS::gmtime_r (const time_t *t, struct tm *res)
344   ACE_OS_TRACE ("ACE_OS::gmtime_r");
345 #if defined (ACE_HAS_REENTRANT_FUNCTIONS)
346   return ace_gmtime_r_helper (t, res);
347 #elif defined (ACE_HAS_TR24731_2005_CRT)
348   struct tm *tm_p = res;
349   ACE_SECURECRTCALL (gmtime_s (res, t), struct tm *, 0, tm_p);
350   return tm_p;
351 #elif defined (ACE_LACKS_GMTIME)
352   ACE_UNUSED_ARG (t);
353   ACE_UNUSED_ARG (res);
354   ACE_NOTSUP_RETURN (0);
355 #else
356   struct tm *result;
357   ACE_OSCALL (::gmtime (t), struct tm *, result) ;
358   if (result != 0)
359     *res = *result;
360   return res;
361 #endif /* ACE_HAS_REENTRANT_FUNCTIONS */
364 ACE_INLINE struct tm *
365 ACE_OS::localtime (const time_t *t)
367   ACE_OS_TRACE ("ACE_OS::localtime");
368 #if defined (ACE_LACKS_LOCALTIME)
369   ACE_UNUSED_ARG (t);
370   ACE_NOTSUP_RETURN (0);
371 #else
372   return ::localtime (t);
373 #endif /* ACE_LACKS_LOCALTIME */
376 ACE_INLINE int
377 ACE_OS::nanosleep (const struct timespec *requested,
378                    struct timespec *remaining)
380   ACE_OS_TRACE ("ACE_OS::nanosleep");
381 #if defined (ACE_HAS_CLOCK_GETTIME)
382   // ::nanosleep () is POSIX 1003.1b.  So is ::clock_gettime ().  So,
383   // if ACE_HAS_CLOCK_GETTIME is defined, then ::nanosleep () should
384   // be available on the platform
385   return ::nanosleep ((ACE_TIMESPEC_PTR) requested, remaining);
386 #else
387   ACE_UNUSED_ARG (remaining);
389   // Convert into seconds and microseconds.
390   ACE_Time_Value tv (requested->tv_sec,
391                      requested->tv_nsec / 1000);
392   return ACE_OS::sleep (tv);
393 #endif /* ACE_HAS_CLOCK_GETTIME */
396 ACE_INLINE size_t
397 ACE_OS::strftime (char *s, size_t maxsize, const char *format,
398                   const struct tm *timeptr)
400 #if defined (ACE_LACKS_STRFTIME)
401   ACE_UNUSED_ARG (s);
402   ACE_UNUSED_ARG (maxsize);
403   ACE_UNUSED_ARG (format);
404   ACE_UNUSED_ARG (timeptr);
405   ACE_NOTSUP_RETURN (0);
406 #else
407   return std::strftime (s, maxsize, format, timeptr);
408 #endif /* ACE_LACKS_STRFTIME */
411 ACE_INLINE char *
412 ACE_OS::strptime (const char *buf, const char *format, struct tm *tm)
414   ACE_OS::memset (tm, 0, sizeof (struct tm));
415 #if defined (ACE_LACKS_STRPTIME)
416   return ACE_OS::strptime_emulation (buf, format, tm);
417 #else
418   return ::strptime (buf, format, tm);
419 #endif /* ACE_LACKS_STRPTIME */
422 ACE_INLINE time_t
423 ACE_OS::time (time_t *tloc)
425   ACE_OS_TRACE ("ACE_OS::time");
426 #if defined (ACE_LACKS_TIME)
427   time_t const retv = ACE_OS::gettimeofday ().sec ();
428   if (tloc)
429     *tloc = retv;
430   return retv;
431 #else
432   return ::time (tloc);
433 #endif /* ACE_LACKS_TIME */
436 // Linux won't compile unless we explicitly use a namespace here.
437 #if defined (__GNUG__)
438 namespace ACE_OS {
439   ACE_INLINE long
440   timezone ()
441   {
442     return ::ace_timezone ();
443   }
444 } /* namespace ACE_OS */
445 #else
446 ACE_INLINE long
447 ACE_OS::timezone ()
449   return ::ace_timezone ();
451 #endif /* ACE_LINUX */
453 ACE_INLINE void
454 ACE_OS::tzset ()
456 #if defined (ACE_LACKS_TZSET)
457   errno = ENOTSUP;
458 #elif defined (ACE_WIN32)
459   ::_tzset ();  // For Win32.
460 #else
461   ::tzset ();   // For UNIX platforms.
462 #endif /* ACE_LACKS_TZSET */
465 ACE_END_VERSIONED_NAMESPACE_DECL