2 * Copyright (c) 2008-2009 Apple Inc. All rights reserved.
4 * @APPLE_APACHE_LICENSE_HEADER_START@
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 * @APPLE_APACHE_LICENSE_HEADER_END@
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.
27 #ifndef __DISPATCH_SHIMS_TIME__
28 #define __DISPATCH_SHIMS_TIME__
30 #ifndef __DISPATCH_INDIRECT__
31 #error "Please #include <dispatch/dispatch.h> instead of this file directly."
34 #if defined(__i386__) || defined(__x86_64__) || !defined(HAVE_MACH_ABSOLUTE_TIME)
35 // these architectures always return mach_absolute_time() in nanoseconds
36 #define _dispatch_time_mach2nano(x) (x)
37 #define _dispatch_time_nano2mach(x) (x)
39 typedef struct _dispatch_host_time_data_s {
43 } _dispatch_host_time_data_s;
44 __private_extern__ _dispatch_host_time_data_s _dispatch_host_time_data;
45 __private_extern__ void _dispatch_get_host_time_init(void *context);
47 static inline uint64_t
48 _dispatch_time_mach2nano(uint64_t machtime)
50 _dispatch_host_time_data_s *const data = &_dispatch_host_time_data;
51 dispatch_once_f(&data->pred, NULL, _dispatch_get_host_time_init);
53 return (uint64_t)(machtime * data->frac);
57 _dispatch_time_nano2mach(int64_t nsec)
59 _dispatch_host_time_data_s *const data = &_dispatch_host_time_data;
60 dispatch_once_f(&data->pred, NULL, _dispatch_get_host_time_init);
62 if (slowpath(_dispatch_host_time_data.ratio_1_to_1)) {
66 long double big_tmp = (long double)nsec;
68 // Divide by tbi.numer/tbi.denom to convert nsec to Mach absolute time
69 big_tmp /= data->frac;
71 // Clamp to a 64bit signed int
72 if (slowpath(big_tmp > INT64_MAX)) {
75 if (slowpath(big_tmp < INT64_MIN)) {
78 return (int64_t)big_tmp;
82 static inline uint64_t
83 _dispatch_absolute_time(void)
85 #if HAVE_MACH_ABSOLUTE_TIME
86 return mach_absolute_time();
91 #if HAVE_DECL_CLOCK_UPTIME
92 ret = clock_gettime(CLOCK_UPTIME, &ts);
93 #elif HAVE_DECL_CLOCK_MONOTONIC
94 ret = clock_gettime(CLOCK_MONOTONIC, &ts);
96 #error "clock_gettime: no supported absolute time clock"
98 (void)dispatch_assume_zero(ret);
100 /* XXXRW: Some kind of overflow detection needed? */
101 return (ts.tv_sec * NSEC_PER_SEC + ts.tv_nsec);
105 #endif /* __DISPATCH_SHIMS_TIME__ */