1/* 2 * Copyright (c) 2008-2013 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#if TARGET_OS_WIN32 35static inline unsigned int 36sleep(unsigned int seconds) 37{ 38 Sleep(seconds * 1000); // milliseconds 39 return 0; 40} 41#endif 42 43uint64_t _dispatch_get_nanoseconds(void); 44 45#if defined(__i386__) || defined(__x86_64__) || !HAVE_MACH_ABSOLUTE_TIME 46// x86 currently implements mach time in nanoseconds 47// this is NOT likely to change 48DISPATCH_ALWAYS_INLINE 49static inline uint64_t 50_dispatch_time_mach2nano(uint64_t machtime) 51{ 52 return machtime; 53} 54 55DISPATCH_ALWAYS_INLINE 56static inline uint64_t 57_dispatch_time_nano2mach(uint64_t nsec) 58{ 59 return nsec; 60} 61#else 62typedef struct _dispatch_host_time_data_s { 63 dispatch_once_t pred; 64 long double frac; 65 bool ratio_1_to_1; 66} _dispatch_host_time_data_s; 67extern _dispatch_host_time_data_s _dispatch_host_time_data; 68void _dispatch_get_host_time_init(void *context); 69 70static inline uint64_t 71_dispatch_time_mach2nano(uint64_t machtime) 72{ 73 _dispatch_host_time_data_s *const data = &_dispatch_host_time_data; 74 dispatch_once_f(&data->pred, NULL, _dispatch_get_host_time_init); 75 76 if (!machtime || slowpath(data->ratio_1_to_1)) { 77 return machtime; 78 } 79 if (machtime >= INT64_MAX) { 80 return INT64_MAX; 81 } 82 long double big_tmp = ((long double)machtime * data->frac) + .5; 83 if (slowpath(big_tmp >= INT64_MAX)) { 84 return INT64_MAX; 85 } 86 return (uint64_t)big_tmp; 87} 88 89static inline uint64_t 90_dispatch_time_nano2mach(uint64_t nsec) 91{ 92 _dispatch_host_time_data_s *const data = &_dispatch_host_time_data; 93 dispatch_once_f(&data->pred, NULL, _dispatch_get_host_time_init); 94 95 if (!nsec || slowpath(data->ratio_1_to_1)) { 96 return nsec; 97 } 98 if (nsec >= INT64_MAX) { 99 return INT64_MAX; 100 } 101 long double big_tmp = ((long double)nsec / data->frac) + .5; 102 if (slowpath(big_tmp >= INT64_MAX)) { 103 return INT64_MAX; 104 } 105 return (uint64_t)big_tmp; 106} 107#endif 108 109static inline uint64_t 110_dispatch_absolute_time(void) 111{ 112#if HAVE_MACH_ABSOLUTE_TIME 113 return mach_absolute_time(); 114#elif TARGET_OS_WIN32 115 LARGE_INTEGER now; 116 return QueryPerformanceCounter(&now) ? now.QuadPart : 0; 117#else 118 struct timespec ts; 119 int ret; 120 121#if HAVE_DECL_CLOCK_UPTIME 122 ret = clock_gettime(CLOCK_UPTIME, &ts); 123#elif HAVE_DECL_CLOCK_MONOTONIC 124 ret = clock_gettime(CLOCK_MONOTONIC, &ts); 125#else 126#error "clock_gettime: no supported absolute time clock" 127#endif 128 (void)dispatch_assume_zero(ret); 129 130 /* XXXRW: Some kind of overflow detection needed? */ 131 return (ts.tv_sec * NSEC_PER_SEC + ts.tv_nsec); 132#endif // HAVE_MACH_ABSOLUTE_TIME 133} 134 135 136#endif // __DISPATCH_SHIMS_TIME__ 137