xref: /php-src/sapi/fpm/fpm/fpm_clock.c (revision 819df032)
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