/src/open62541/arch/posix/clock_posix.c
Line | Count | Source |
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 | 0 | UA_DateTime UA_DateTime_now(void) { |
27 | 0 | struct timeval tv; |
28 | 0 | gettimeofday(&tv, NULL); |
29 | 0 | return (tv.tv_sec * UA_DATETIME_SEC) + |
30 | 0 | (tv.tv_usec * UA_DATETIME_USEC) + |
31 | 0 | UA_DATETIME_UNIX_EPOCH; |
32 | 0 | } |
33 | | |
34 | | /* Compare broken-down representations of the same instant. Avoid mktime(), |
35 | | * which interprets UTC fields as local time and refreshes global timezone state. */ |
36 | 0 | UA_Int64 UA_DateTime_localTimeUtcOffset(void) { |
37 | 0 | time_t rawtime = time(NULL); |
38 | 0 | struct tm local, utc; |
39 | 0 | if(!localtime_r(&rawtime, &local) || !gmtime_r(&rawtime, &utc)) |
40 | 0 | return 0; |
41 | 0 | int days = local.tm_yday - utc.tm_yday; |
42 | 0 | if(local.tm_year != utc.tm_year) |
43 | 0 | days = (local.tm_year > utc.tm_year) ? 1 : -1; |
44 | 0 | return ((UA_Int64)days * 86400 + (local.tm_hour - utc.tm_hour) * 3600 + |
45 | 0 | (local.tm_min - utc.tm_min) * 60 + local.tm_sec - utc.tm_sec) * UA_DATETIME_SEC; |
46 | 0 | } |
47 | | |
48 | 0 | UA_DateTime UA_DateTime_nowMonotonic(void) { |
49 | | #if defined(__APPLE__) && defined(__MACH__) |
50 | | /* OS X does not have clock_gettime, use clock_get_time */ |
51 | | clock_serv_t cclock; |
52 | | mach_timespec_t mts; |
53 | | host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cclock); |
54 | | clock_get_time(cclock, &mts); |
55 | | mach_port_deallocate(mach_task_self(), cclock); |
56 | | return (mts.tv_sec * UA_DATETIME_SEC) + (mts.tv_nsec / 100) + UA_DATETIME_UNIX_EPOCH; |
57 | | #elif !defined(CLOCK_MONOTONIC_RAW) |
58 | | struct timespec ts; |
59 | | clock_gettime(CLOCK_MONOTONIC, &ts); |
60 | | return (ts.tv_sec * UA_DATETIME_SEC) + (ts.tv_nsec / 100) + UA_DATETIME_UNIX_EPOCH; |
61 | | #else |
62 | 0 | struct timespec ts; |
63 | 0 | clock_gettime(CLOCK_MONOTONIC_RAW, &ts); |
64 | 0 | return (ts.tv_sec * UA_DATETIME_SEC) + (ts.tv_nsec / 100) + UA_DATETIME_UNIX_EPOCH; |
65 | 0 | #endif |
66 | 0 | } |
67 | | |
68 | | #endif /* UA_ARCHITECTURE_POSIX */ |