/src/open62541/arch/posix/clock_posix.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* This work is licensed under a Creative Commons CCZero 1.0 Universal License. |
2 | | * See http://creativecommons.org/publicdomain/zero/1.0/ for more information. |
3 | | * |
4 | | * Copyright 2016-2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer) |
5 | | * Copyright 2017 (c) Stefan Profanter, fortiss GmbH |
6 | | * Copyright 2017 (c) Thomas Stalder, Blue Time Concept SA |
7 | | */ |
8 | | |
9 | | #include <open62541/types.h> |
10 | | |
11 | | /* Note that the EventLoop plugin provides its own internal time source (which |
12 | | * is typically just the normal system time). All internal access to the time |
13 | | * source should be through the EventLoop. The below is therefore for developer |
14 | | * convenience to just use UA_DateTime_now(). */ |
15 | | |
16 | | #if defined(UA_ARCHITECTURE_POSIX) |
17 | | |
18 | | #include <time.h> |
19 | | #include <sys/time.h> |
20 | | |
21 | | #if defined(__APPLE__) || defined(__MACH__) |
22 | | # include <mach/clock.h> |
23 | | # include <mach/mach.h> |
24 | | #endif |
25 | | |
26 | 1.31k | UA_DateTime UA_DateTime_now(void) { |
27 | 1.31k | struct timeval tv; |
28 | 1.31k | gettimeofday(&tv, NULL); |
29 | 1.31k | return (tv.tv_sec * UA_DATETIME_SEC) + |
30 | 1.31k | (tv.tv_usec * UA_DATETIME_USEC) + |
31 | 1.31k | UA_DATETIME_UNIX_EPOCH; |
32 | 1.31k | } |
33 | | |
34 | | /* Credit to https://stackoverflow.com/questions/13804095/get-the-time-zone-gmt-offset-in-c */ |
35 | 177 | UA_Int64 UA_DateTime_localTimeUtcOffset(void) { |
36 | 177 | time_t rawtime = time(NULL); |
37 | 177 | struct tm gbuf; |
38 | 177 | struct tm *ptm = gmtime_r(&rawtime, &gbuf); |
39 | | /* Request mktime() to look up dst in timezone database */ |
40 | 177 | ptm->tm_isdst = -1; |
41 | 177 | time_t gmt = mktime(ptm); |
42 | 177 | return (UA_Int64) (difftime(rawtime, gmt) * UA_DATETIME_SEC); |
43 | 177 | } |
44 | | |
45 | 0 | UA_DateTime UA_DateTime_nowMonotonic(void) { |
46 | | #if defined(__APPLE__) || defined(__MACH__) |
47 | | /* OS X does not have clock_gettime, use clock_get_time */ |
48 | | clock_serv_t cclock; |
49 | | mach_timespec_t mts; |
50 | | host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cclock); |
51 | | clock_get_time(cclock, &mts); |
52 | | mach_port_deallocate(mach_task_self(), cclock); |
53 | | return (mts.tv_sec * UA_DATETIME_SEC) + (mts.tv_nsec / 100); |
54 | | #elif !defined(CLOCK_MONOTONIC_RAW) |
55 | | struct timespec ts; |
56 | | clock_gettime(CLOCK_MONOTONIC, &ts); |
57 | | return (ts.tv_sec * UA_DATETIME_SEC) + (ts.tv_nsec / 100); |
58 | | #else |
59 | 0 | struct timespec ts; |
60 | 0 | clock_gettime(CLOCK_MONOTONIC_RAW, &ts); |
61 | 0 | return (ts.tv_sec * UA_DATETIME_SEC) + (ts.tv_nsec / 100); |
62 | 0 | #endif |
63 | 0 | } |
64 | | |
65 | | #elif defined(UA_ARCHITECTURE_WIN32) |
66 | | |
67 | | #include <time.h> |
68 | | /* Backup definition of SLIST_ENTRY on mingw winnt.h */ |
69 | | # ifdef SLIST_ENTRY |
70 | | # pragma push_macro("SLIST_ENTRY") |
71 | | # undef SLIST_ENTRY |
72 | | # define POP_SLIST_ENTRY |
73 | | # endif |
74 | | # include <windows.h> |
75 | | /* restore definition */ |
76 | | # ifdef POP_SLIST_ENTRY |
77 | | # undef SLIST_ENTRY |
78 | | # undef POP_SLIST_ENTRY |
79 | | # pragma pop_macro("SLIST_ENTRY") |
80 | | # endif |
81 | | |
82 | | /* Windows filetime has the same definition as UA_DateTime */ |
83 | | UA_DateTime |
84 | | UA_DateTime_now(void) { |
85 | | FILETIME ft; |
86 | | SYSTEMTIME st; |
87 | | GetSystemTime(&st); |
88 | | SystemTimeToFileTime(&st, &ft); |
89 | | ULARGE_INTEGER ul; |
90 | | ul.LowPart = ft.dwLowDateTime; |
91 | | ul.HighPart = ft.dwHighDateTime; |
92 | | return (UA_DateTime)ul.QuadPart; |
93 | | } |
94 | | |
95 | | /* Credit to https://stackoverflow.com/questions/13804095/get-the-time-zone-gmt-offset-in-c */ |
96 | | UA_Int64 |
97 | | UA_DateTime_localTimeUtcOffset(void) { |
98 | | time_t rawtime = time(NULL); |
99 | | struct tm ptm; |
100 | | #ifdef __CODEGEARC__ |
101 | | gmtime_s(&rawtime, &ptm); |
102 | | #else |
103 | | gmtime_s(&ptm, &rawtime); |
104 | | #endif |
105 | | |
106 | | /* Request mktime() to look up dst in timezone database */ |
107 | | ptm.tm_isdst = -1; |
108 | | time_t gmt = mktime(&ptm); |
109 | | |
110 | | return (UA_Int64) (difftime(rawtime, gmt) * UA_DATETIME_SEC); |
111 | | } |
112 | | |
113 | | UA_DateTime |
114 | | UA_DateTime_nowMonotonic(void) { |
115 | | LARGE_INTEGER freq, ticks; |
116 | | QueryPerformanceFrequency(&freq); |
117 | | QueryPerformanceCounter(&ticks); |
118 | | UA_Double ticks2dt = UA_DATETIME_SEC / (UA_Double)freq.QuadPart; |
119 | | return (UA_DateTime)(ticks.QuadPart * ticks2dt); |
120 | | } |
121 | | |
122 | | #endif /* UA_ARCHITECTURE_WIN32 */ |