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