]> www.ginac.de Git - cln.git/blob - src/timing/cl_t_current.cc
Fix compilation error on MSVC.
[cln.git] / src / timing / cl_t_current.cc
1 // cl_current_time().
2
3 #if defined(_WIN32) && !defined(__CYGWIN__)
4 #include <windows.h> // For GetSystemTimeAsFileTime(), must be included first, sorry.
5 #endif
6
7 // General includes.
8 #include "base/cl_sysdep.h"
9
10 // Specification.
11 #include "cln/timing.h"
12
13
14 // Implementation.
15
16 #include "timing/cl_t_config.h"
17
18
19 #if defined(HAVE_GETTIMEOFDAY)
20   #include <sys/time.h>
21   #ifdef GETTIMEOFDAY_DOTS
22     extern "C" int gettimeofday (struct timeval * tp, ...);
23   #else
24     extern "C" int gettimeofday (struct timeval * tp, GETTIMEOFDAY_TZP_T tzp);
25   #endif
26 #elif defined(_WIN32) && !defined(__CYGWIN__)
27   /* <windows.h> included above. */
28 #else
29   #include <ctime>
30 #endif
31 #ifdef HAVE_PERROR_DECL
32   #include <cerrno>
33   #include <cstdio>
34 #else
35   extern "C" int perror (const char *);
36 #endif
37
38 namespace cln {
39
40 const cl_timespec cl_current_time ()
41 {
42 #if defined(HAVE_GETTIMEOFDAY)
43         var struct timeval tv;
44         if (gettimeofday(&tv,NULL) != 0) {
45                 perror("gettimeofday");
46                 tv.tv_sec = 0; tv.tv_usec = 0;
47         }
48         return cl_timespec(tv.tv_sec,
49                            tv.tv_usec * (1000000000/1000000)
50                           );
51 #elif defined(_WIN32) && !defined(__CYGWIN__)
52
53         /* GetSystemTimePreciseAsFileTime was introduced only in Windows 8.  */
54         typedef void (WINAPI * GetSystemTimePreciseAsFileTimeFuncType) (FILETIME *lpTime);
55         static GetSystemTimePreciseAsFileTimeFuncType GetSystemTimePreciseAsFileTimeFunc = NULL;
56         static BOOL initialized = FALSE;
57
58         if (!initialized) {
59                 HMODULE kernel32 = LoadLibrary ("kernel32.dll");
60                 if (kernel32 != NULL) {
61                         GetSystemTimePreciseAsFileTimeFunc =
62                                 (GetSystemTimePreciseAsFileTimeFuncType) (void *) GetProcAddress (kernel32, "GetSystemTimePreciseAsFileTime");
63                 }
64                 initialized = TRUE;
65         }
66
67         FILETIME current_time;
68
69         if (GetSystemTimePreciseAsFileTimeFunc != NULL)
70                 GetSystemTimePreciseAsFileTimeFunc (&current_time);
71         else
72                 GetSystemTimeAsFileTime (&current_time);
73
74         /* Convert from FILETIME to 'struct timeval'.  */
75         /* FILETIME: <https://docs.microsoft.com/en-us/windows/desktop/api/minwinbase/ns-minwinbase-filetime> */
76         ULONGLONG since_1601 =
77                 ((ULONGLONG) current_time.dwHighDateTime << 32)
78                 | (ULONGLONG) current_time.dwLowDateTime;
79         /* Between 1601-01-01 and 1970-01-01 there were 280 normal years and 89 leap
80            years, in total 134774 days.  */
81         ULONGLONG since_1970 =
82                 since_1601 - (ULONGLONG) 134774 * (ULONGLONG) 86400 * (ULONGLONG) 10000000;
83         ULONGLONG microseconds_since_1970 = since_1970 / (ULONGLONG) 10;
84         return cl_timespec(microseconds_since_1970 / (ULONGLONG) 1000000,
85                            (microseconds_since_1970 % (ULONGLONG) 1000000) * (1000000000/1000000)
86                           );
87
88 #else
89         return cl_timespec(time(NULL),0);
90 #endif
91 }
92
93 }  // namespace cln