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