1 /* (c) 2007,2008 Andrei Nigmatulin */
2
3 #include "fpm_config.h"
4
5 #ifdef HAVE_CLOCK_GETTIME
6 #include <time.h> /* for CLOCK_MONOTONIC */
7 #endif
8
9 #include "fpm_clock.h"
10 #include "zlog.h"
11
12
13 /* posix monotonic clock - preferred source of time */
14 #if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
15
16 static int monotonic_works;
17
fpm_clock_init(void)18 int fpm_clock_init(void)
19 {
20 struct timespec ts;
21
22 monotonic_works = 0;
23
24 if (0 == clock_gettime(CLOCK_MONOTONIC, &ts)) {
25 monotonic_works = 1;
26 }
27
28 return 0;
29 }
30
fpm_clock_get(struct timeval * tv)31 int fpm_clock_get(struct timeval *tv) /* {{{ */
32 {
33 if (monotonic_works) {
34 struct timespec ts;
35
36 if (0 > clock_gettime(CLOCK_MONOTONIC, &ts)) {
37 zlog(ZLOG_SYSERROR, "clock_gettime() failed");
38 return -1;
39 }
40
41 tv->tv_sec = ts.tv_sec;
42 tv->tv_usec = ts.tv_nsec / 1000;
43 return 0;
44 }
45
46 return gettimeofday(tv, 0);
47 }
48 /* }}} */
49
50 /* macOS clock */
51 #elif defined(HAVE_CLOCK_GET_TIME)
52
53 #include <mach/mach.h>
54 #include <mach/clock.h>
55 #include <mach/mach_error.h>
56
57 static clock_serv_t mach_clock;
58
59 /* this code borrowed from here: http://lists.apple.com/archives/Darwin-development/2002/Mar/msg00746.html */
60 /* mach_clock also should be re-initialized in child process after fork */
fpm_clock_init(void)61 int fpm_clock_init(void)
62 {
63 kern_return_t ret;
64 mach_timespec_t aTime;
65
66 ret = host_get_clock_service(mach_host_self(), REALTIME_CLOCK, &mach_clock);
67
68 if (ret != KERN_SUCCESS) {
69 zlog(ZLOG_ERROR, "host_get_clock_service() failed: %s", mach_error_string(ret));
70 return -1;
71 }
72
73 /* test if it works */
74 ret = clock_get_time(mach_clock, &aTime);
75
76 if (ret != KERN_SUCCESS) {
77 zlog(ZLOG_ERROR, "clock_get_time() failed: %s", mach_error_string(ret));
78 return -1;
79 }
80
81 return 0;
82 }
83
fpm_clock_get(struct timeval * tv)84 int fpm_clock_get(struct timeval *tv) /* {{{ */
85 {
86 kern_return_t ret;
87 mach_timespec_t aTime;
88
89 ret = clock_get_time(mach_clock, &aTime);
90
91 if (ret != KERN_SUCCESS) {
92 zlog(ZLOG_ERROR, "clock_get_time() failed: %s", mach_error_string(ret));
93 return -1;
94 }
95
96 tv->tv_sec = aTime.tv_sec;
97 tv->tv_usec = aTime.tv_nsec / 1000;
98
99 return 0;
100 }
101 /* }}} */
102
103 #else /* no clock */
104
fpm_clock_init(void)105 int fpm_clock_init(void)
106 {
107 return 0;
108 }
109
fpm_clock_get(struct timeval * tv)110 int fpm_clock_get(struct timeval *tv) /* {{{ */
111 {
112 return gettimeofday(tv, 0);
113 }
114 /* }}} */
115
116 #endif
117