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@
24 _dispatch_get_nanoseconds(void)
27 int r = gettimeofday(&now, NULL);
28 dispatch_assert_zero(r);
29 dispatch_assert(sizeof(NSEC_PER_SEC) == 8);
30 dispatch_assert(sizeof(NSEC_PER_USEC) == 8);
31 return now.tv_sec * NSEC_PER_SEC + now.tv_usec * NSEC_PER_USEC;
35 dispatch_time(dispatch_time_t inval, int64_t delta)
37 if (inval == DISPATCH_TIME_FOREVER) {
38 return DISPATCH_TIME_FOREVER;
40 if ((int64_t)inval < 0) {
43 if ((int64_t)(inval -= delta) >= 0) {
44 return DISPATCH_TIME_FOREVER; // overflow
48 if ((int64_t)(inval -= delta) >= -1) {
49 // -1 is special == DISPATCH_TIME_FOREVER == forever
50 return -2; // underflow
55 delta = _dispatch_time_nano2mach(delta);
57 inval = _dispatch_absolute_time();
60 if ((int64_t)(inval += delta) <= 0) {
61 return DISPATCH_TIME_FOREVER; // overflow
65 if ((int64_t)(inval += delta) < 1) {
66 return 1; // underflow
72 dispatch_walltime(const struct timespec *inval, int64_t delta)
77 nsec = inval->tv_sec * 1000000000ull + inval->tv_nsec;
79 nsec = _dispatch_get_nanoseconds();
84 // -1 is special == DISPATCH_TIME_FOREVER == forever
85 return delta >= 0 ? DISPATCH_TIME_FOREVER : (uint64_t)-2ll;
92 _dispatch_timeout(dispatch_time_t when)
96 if (when == DISPATCH_TIME_FOREVER) {
97 return DISPATCH_TIME_FOREVER;
102 if ((int64_t)when < 0) {
103 when = -(int64_t)when;
104 now = _dispatch_get_nanoseconds();
105 return now >= when ? 0 : when - now;
107 now = _dispatch_absolute_time();
108 return now >= when ? 0 : _dispatch_time_mach2nano(when - now);
113 * Unlike Mach semaphores, POSIX semaphores take an absolute, real time as an
114 * argument to sem_timedwait(). This routine converts from dispatch_time_t
115 * but assumes the caller has already handled the possibility of
116 * DISPATCH_TIME_FOREVER.
119 _dispatch_timeout_ts(dispatch_time_t when)
121 struct timespec ts_realtime;
122 uint64_t abstime, realtime;
126 ret = clock_gettime(CLOCK_REALTIME, &ts_realtime);
127 (void)dispatch_assume_zero(ret);
128 return (ts_realtime);
130 if ((int64_t)when < 0) {
131 ret = clock_gettime(CLOCK_REALTIME, &ts_realtime);
132 (void)dispatch_assume_zero(ret);
133 when = -(int64_t)when + ts_realtime.tv_sec * NSEC_PER_SEC +
135 ts_realtime.tv_sec = when / NSEC_PER_SEC;
136 ts_realtime.tv_nsec = when % NSEC_PER_SEC;
137 return (ts_realtime);
141 * Rebase 'when': (when - abstime) + realtime.
143 * XXXRW: Should we cache this delta to avoid system calls?
145 abstime = _dispatch_absolute_time();
146 ret = clock_gettime(CLOCK_REALTIME, &ts_realtime);
147 (void)dispatch_assume_zero(ret);
148 realtime = ts_realtime.tv_sec * NSEC_PER_SEC + ts_realtime.tv_nsec +
150 ts_realtime.tv_sec = realtime / NSEC_PER_SEC;
151 ts_realtime.tv_nsec = realtime % NSEC_PER_SEC;
152 return (ts_realtime);