]> git.saurik.com Git - apple/libdispatch.git/blob - src/shims/time.h
libdispatch-187.5.tar.gz
[apple/libdispatch.git] / src / shims / time.h
1 /*
2 * Copyright (c) 2008-2011 Apple Inc. All rights reserved.
3 *
4 * @APPLE_APACHE_LICENSE_HEADER_START@
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 * @APPLE_APACHE_LICENSE_HEADER_END@
19 */
20
21 /*
22 * IMPORTANT: This header file describes INTERNAL interfaces to libdispatch
23 * which are subject to change in future releases of Mac OS X. Any applications
24 * relying on these interfaces WILL break.
25 */
26
27 #ifndef __DISPATCH_SHIMS_TIME__
28 #define __DISPATCH_SHIMS_TIME__
29
30 #ifndef __DISPATCH_INDIRECT__
31 #error "Please #include <dispatch/dispatch.h> instead of this file directly."
32 #endif
33
34 uint64_t _dispatch_get_nanoseconds(void);
35
36 #if defined(__i386__) || defined(__x86_64__) || !HAVE_MACH_ABSOLUTE_TIME
37 // x86 currently implements mach time in nanoseconds
38 // this is NOT likely to change
39 #define _dispatch_time_mach2nano(x) ({x;})
40 #define _dispatch_time_nano2mach(x) ({x;})
41 #else
42 typedef struct _dispatch_host_time_data_s {
43 long double frac;
44 bool ratio_1_to_1;
45 dispatch_once_t pred;
46 } _dispatch_host_time_data_s;
47 extern _dispatch_host_time_data_s _dispatch_host_time_data;
48 void _dispatch_get_host_time_init(void *context);
49
50 static inline uint64_t
51 _dispatch_time_mach2nano(uint64_t machtime)
52 {
53 _dispatch_host_time_data_s *const data = &_dispatch_host_time_data;
54 dispatch_once_f(&data->pred, NULL, _dispatch_get_host_time_init);
55
56 return machtime * data->frac;
57 }
58
59 static inline int64_t
60 _dispatch_time_nano2mach(int64_t nsec)
61 {
62 _dispatch_host_time_data_s *const data = &_dispatch_host_time_data;
63 dispatch_once_f(&data->pred, NULL, _dispatch_get_host_time_init);
64
65 if (slowpath(_dispatch_host_time_data.ratio_1_to_1)) {
66 return nsec;
67 }
68
69 long double big_tmp = nsec;
70
71 // Divide by tbi.numer/tbi.denom to convert nsec to Mach absolute time
72 big_tmp /= data->frac;
73
74 // Clamp to a 64bit signed int
75 if (slowpath(big_tmp > INT64_MAX)) {
76 return INT64_MAX;
77 }
78 if (slowpath(big_tmp < INT64_MIN)) {
79 return INT64_MIN;
80 }
81 return big_tmp;
82 }
83 #endif
84
85 static inline uint64_t
86 _dispatch_absolute_time(void)
87 {
88 #if !HAVE_MACH_ABSOLUTE_TIME
89 struct timespec ts;
90 int ret;
91
92 #if HAVE_DECL_CLOCK_UPTIME
93 ret = clock_gettime(CLOCK_UPTIME, &ts);
94 #elif HAVE_DECL_CLOCK_MONOTONIC
95 ret = clock_gettime(CLOCK_MONOTONIC, &ts);
96 #else
97 #error "clock_gettime: no supported absolute time clock"
98 #endif
99 (void)dispatch_assume_zero(ret);
100
101 /* XXXRW: Some kind of overflow detection needed? */
102 return (ts.tv_sec * NSEC_PER_SEC + ts.tv_nsec);
103 #else
104 return mach_absolute_time();
105 #endif
106 }
107
108 #endif