Tizen 2.1 base
[platform/upstream/gcd.git] / dispatch-1.0 / src / shims / time.h
1 /*
2  * Copyright (c) 2008-2009 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 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)
38 #else
39 typedef struct _dispatch_host_time_data_s {
40         long double frac;
41         bool ratio_1_to_1;
42         dispatch_once_t pred;
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);
46
47 static inline uint64_t
48 _dispatch_time_mach2nano(uint64_t machtime)
49 {
50         _dispatch_host_time_data_s *const data = &_dispatch_host_time_data;
51         dispatch_once_f(&data->pred, NULL, _dispatch_get_host_time_init);
52
53         return (uint64_t)(machtime * data->frac);
54 }
55
56 static inline int64_t
57 _dispatch_time_nano2mach(int64_t nsec)
58 {
59         _dispatch_host_time_data_s *const data = &_dispatch_host_time_data;
60         dispatch_once_f(&data->pred, NULL, _dispatch_get_host_time_init);
61
62         if (slowpath(_dispatch_host_time_data.ratio_1_to_1)) {
63                 return nsec;
64         }
65
66         long double big_tmp = (long double)nsec;
67
68         // Divide by tbi.numer/tbi.denom to convert nsec to Mach absolute time
69         big_tmp /= data->frac;
70
71         // Clamp to a 64bit signed int
72         if (slowpath(big_tmp > INT64_MAX)) {
73                 return INT64_MAX;
74         }
75         if (slowpath(big_tmp < INT64_MIN)) {
76                 return INT64_MIN;
77         }
78         return (int64_t)big_tmp;
79 }
80 #endif
81
82 static inline uint64_t
83 _dispatch_absolute_time(void)
84 {
85 #if HAVE_MACH_ABSOLUTE_TIME
86         return mach_absolute_time();
87 #else
88         struct timespec ts;
89         int ret;
90
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);
95 #else
96 #error "clock_gettime: no supported absolute time clock"
97 #endif
98         (void)dispatch_assume_zero(ret);
99
100         /* XXXRW: Some kind of overflow detection needed? */
101         return (ts.tv_sec * NSEC_PER_SEC + ts.tv_nsec);
102 #endif
103 }
104
105 #endif /* __DISPATCH_SHIMS_TIME__ */