2 * Copyright (c) 2008-2013 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@
23 #if DISPATCH_USE_HOST_TIME
24 typedef struct _dispatch_host_time_data_s
{
27 } _dispatch_host_time_data_s
;
29 DISPATCH_CACHELINE_ALIGN
30 static _dispatch_host_time_data_s _dispatch_host_time_data
;
32 uint64_t (*_dispatch_host_time_mach2nano
)(uint64_t machtime
);
33 uint64_t (*_dispatch_host_time_nano2mach
)(uint64_t nsec
);
36 _dispatch_mach_host_time_mach2nano(uint64_t machtime
)
38 _dispatch_host_time_data_s
*const data
= &_dispatch_host_time_data
;
40 if (unlikely(!machtime
|| data
->ratio_1_to_1
)) {
43 if (machtime
>= INT64_MAX
) {
46 long double big_tmp
= ((long double)machtime
* data
->frac
) + .5L;
47 if (unlikely(big_tmp
>= INT64_MAX
)) {
50 return (uint64_t)big_tmp
;
54 _dispatch_mach_host_time_nano2mach(uint64_t nsec
)
56 _dispatch_host_time_data_s
*const data
= &_dispatch_host_time_data
;
58 if (unlikely(!nsec
|| data
->ratio_1_to_1
)) {
61 if (nsec
>= INT64_MAX
) {
64 long double big_tmp
= ((long double)nsec
/ data
->frac
) + .5L;
65 if (unlikely(big_tmp
>= INT64_MAX
)) {
68 return (uint64_t)big_tmp
;
72 _dispatch_host_time_init(mach_timebase_info_data_t
*tbi
)
74 _dispatch_host_time_data
.frac
= tbi
->numer
;
75 _dispatch_host_time_data
.frac
/= tbi
->denom
;
76 _dispatch_host_time_data
.ratio_1_to_1
= (tbi
->numer
== tbi
->denom
);
77 _dispatch_host_time_mach2nano
= _dispatch_mach_host_time_mach2nano
;
78 _dispatch_host_time_nano2mach
= _dispatch_mach_host_time_nano2mach
;
80 #endif // DISPATCH_USE_HOST_TIME
83 _dispatch_time_init(void)
85 #if DISPATCH_USE_HOST_TIME
86 mach_timebase_info_data_t tbi
;
87 (void)dispatch_assume_zero(mach_timebase_info(&tbi
));
88 _dispatch_host_time_init(&tbi
);
89 #endif // DISPATCH_USE_HOST_TIME
93 dispatch_time(dispatch_time_t inval
, int64_t delta
)
96 if (inval
== DISPATCH_TIME_FOREVER
) {
97 return DISPATCH_TIME_FOREVER
;
99 if ((int64_t)inval
< 0) {
102 offset
= (uint64_t)delta
;
103 if ((int64_t)(inval
-= offset
) >= 0) {
104 return DISPATCH_TIME_FOREVER
; // overflow
108 offset
= (uint64_t)-delta
;
109 if ((int64_t)(inval
+= offset
) >= -1) {
110 // -1 is special == DISPATCH_TIME_FOREVER == forever
111 return (dispatch_time_t
)-2ll; // underflow
118 inval
= _dispatch_absolute_time();
121 offset
= _dispatch_time_nano2mach((uint64_t)delta
);
122 if ((int64_t)(inval
+= offset
) <= 0) {
123 return DISPATCH_TIME_FOREVER
; // overflow
127 offset
= _dispatch_time_nano2mach((uint64_t)-delta
);
128 if ((int64_t)(inval
-= offset
) < 1) {
129 return 1; // underflow
136 dispatch_walltime(const struct timespec
*inval
, int64_t delta
)
140 nsec
= (int64_t)_dispatch_timespec_to_nano(*inval
);
142 nsec
= (int64_t)_dispatch_get_nanoseconds();
146 // -1 is special == DISPATCH_TIME_FOREVER == forever
147 return delta
>= 0 ? DISPATCH_TIME_FOREVER
: (dispatch_time_t
)-2ll;
149 return (dispatch_time_t
)-nsec
;
153 _dispatch_timeout(dispatch_time_t when
)
156 if (when
== DISPATCH_TIME_FOREVER
) {
157 return DISPATCH_TIME_FOREVER
;
162 if ((int64_t)when
< 0) {
163 when
= (dispatch_time_t
)-(int64_t)when
;
164 now
= _dispatch_get_nanoseconds();
165 return now
>= when
? 0 : when
- now
;
167 now
= _dispatch_absolute_time();
168 return now
>= when
? 0 : _dispatch_time_mach2nano(when
- now
);
172 _dispatch_time_nanoseconds_since_epoch(dispatch_time_t when
)
174 if (when
== DISPATCH_TIME_FOREVER
) {
175 return DISPATCH_TIME_FOREVER
;
177 if ((int64_t)when
< 0) {
178 // time in nanoseconds since the POSIX epoch already
179 return (uint64_t)-(int64_t)when
;
181 return _dispatch_get_nanoseconds() + _dispatch_timeout(when
);