9
9
#include " chrono"
10
10
#include " cerrno" // errno
11
11
#include " system_error" // __throw_system_error
12
- #include < time.h> // clock_gettime, CLOCK_MONOTONIC and CLOCK_REALTIME
12
+ #include < time.h> // clock_gettime and CLOCK_{MONOTONIC,REALTIME,MONOTONIC_RAW}
13
13
#include " include/apple_availability.h"
14
14
15
15
#if __has_include(<unistd.h>)
21
21
#endif
22
22
23
23
#if defined(_LIBCPP_WIN32API)
24
- #define WIN32_LEAN_AND_MEAN
25
- #define VC_EXTRA_LEAN
26
- #include < windows.h>
27
- #if _WIN32_WINNT >= _WIN32_WINNT_WIN8
28
- #include < winapifamily.h>
29
- #endif
24
+ # define WIN32_LEAN_AND_MEAN
25
+ # define VC_EXTRA_LEAN
26
+ # include < windows.h>
27
+ # if _WIN32_WINNT >= _WIN32_WINNT_WIN8
28
+ # include < winapifamily.h>
29
+ # endif
30
30
#else
31
- #if !defined(CLOCK_REALTIME) || !defined(_LIBCPP_USE_CLOCK_GETTIME )
32
- #include < sys/time.h> // for gettimeofday and timeval
33
- #endif
31
+ # if !defined(CLOCK_REALTIME )
32
+ # include < sys/time.h> // for gettimeofday and timeval
33
+ # endif // !defined(CLOCK_REALTIME)
34
34
#endif // defined(_LIBCPP_WIN32API)
35
35
36
- #if !defined(_LIBCPP_HAS_NO_MONOTONIC_CLOCK)
37
- #if __APPLE__
38
- #include < mach/mach_time.h> // mach_absolute_time, mach_timebase_info_data_t
39
- #elif !defined(_LIBCPP_WIN32API) && !defined(CLOCK_MONOTONIC)
40
- #error "Monotonic clock not implemented"
41
- #endif
42
- #endif
43
-
44
36
#if defined(__ELF__) && defined(_LIBCPP_LINK_RT_LIB)
45
- #pragma comment(lib, "rt")
37
+ # pragma comment(lib, "rt")
46
38
#endif
47
39
48
40
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -82,7 +74,7 @@ system_clock::now() _NOEXCEPT
82
74
static_cast <__int64>(ft.dwLowDateTime )};
83
75
return time_point (duration_cast<duration>(d - nt_to_unix_epoch));
84
76
#else
85
- #if defined(_LIBCPP_USE_CLOCK_GETTIME) && defined( CLOCK_REALTIME)
77
+ #if defined(CLOCK_REALTIME)
86
78
struct timespec tp;
87
79
if (0 != clock_gettime (CLOCK_REALTIME, &tp))
88
80
__throw_system_error (errno, " clock_gettime(CLOCK_REALTIME) failed" );
@@ -91,7 +83,7 @@ system_clock::now() _NOEXCEPT
91
83
timeval tv;
92
84
gettimeofday (&tv, 0 );
93
85
return time_point (seconds (tv.tv_sec ) + microseconds (tv.tv_usec ));
94
- #endif // _LIBCPP_USE_CLOCK_GETTIME && CLOCK_REALTIME
86
+ #endif // CLOCK_REALTIME
95
87
#endif
96
88
}
97
89
@@ -118,8 +110,15 @@ const bool steady_clock::is_steady;
118
110
119
111
#if defined(__APPLE__)
120
112
121
- // Darwin libc versions >= 1133 provide ns precision via CLOCK_MONOTONIC_RAW
122
- #if defined(_LIBCPP_USE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC_RAW)
113
+ #if !defined(CLOCK_MONOTONIC_RAW)
114
+ # error "Building libc++ on Apple platforms requires CLOCK_MONOTONIC_RAW"
115
+ #endif
116
+
117
+ // On Apple platforms, only CLOCK_UPTIME_RAW, CLOCK_MONOTONIC_RAW or
118
+ // mach_absolute_time are able to time functions in the nanosecond range.
119
+ // Furthermore, only CLOCK_MONOTONIC_RAW is truly monotonic, because it
120
+ // also counts cycles when the system is asleep. Thus, it is the only
121
+ // acceptable implementation of steady_clock.
123
122
steady_clock::time_point
124
123
steady_clock::now () _NOEXCEPT
125
124
{
@@ -129,60 +128,6 @@ steady_clock::now() _NOEXCEPT
129
128
return time_point (seconds (tp.tv_sec ) + nanoseconds (tp.tv_nsec ));
130
129
}
131
130
132
- #else
133
- // mach_absolute_time() * MachInfo.numer / MachInfo.denom is the number of
134
- // nanoseconds since the computer booted up. MachInfo.numer and MachInfo.denom
135
- // are run time constants supplied by the OS. This clock has no relationship
136
- // to the Gregorian calendar. It's main use is as a high resolution timer.
137
-
138
- // MachInfo.numer / MachInfo.denom is often 1 on the latest equipment. Specialize
139
- // for that case as an optimization.
140
-
141
- static
142
- steady_clock::rep
143
- steady_simplified ()
144
- {
145
- return static_cast <steady_clock::rep>(mach_absolute_time ());
146
- }
147
-
148
- static
149
- double
150
- compute_steady_factor ()
151
- {
152
- mach_timebase_info_data_t MachInfo;
153
- mach_timebase_info (&MachInfo);
154
- return static_cast <double >(MachInfo.numer ) / MachInfo.denom ;
155
- }
156
-
157
- static
158
- steady_clock::rep
159
- steady_full ()
160
- {
161
- static const double factor = compute_steady_factor ();
162
- return static_cast <steady_clock::rep>(mach_absolute_time () * factor);
163
- }
164
-
165
- typedef steady_clock::rep (*FP)();
166
-
167
- static
168
- FP
169
- init_steady_clock ()
170
- {
171
- mach_timebase_info_data_t MachInfo;
172
- mach_timebase_info (&MachInfo);
173
- if (MachInfo.numer == MachInfo.denom )
174
- return &steady_simplified;
175
- return &steady_full;
176
- }
177
-
178
- steady_clock::time_point
179
- steady_clock::now () _NOEXCEPT
180
- {
181
- static FP fp = init_steady_clock ();
182
- return time_point (duration (fp ()));
183
- }
184
- #endif // defined(_LIBCPP_USE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC_RAW)
185
-
186
131
#elif defined(_LIBCPP_WIN32API)
187
132
188
133
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms644905(v=vs.85).aspx says:
@@ -210,13 +155,6 @@ steady_clock::now() _NOEXCEPT
210
155
211
156
#elif defined(CLOCK_MONOTONIC)
212
157
213
- // On Apple platforms only CLOCK_UPTIME_RAW, CLOCK_MONOTONIC_RAW or
214
- // mach_absolute_time are able to time functions in the nanosecond range.
215
- // Thus, they are the only acceptable implementations of steady_clock.
216
- #ifdef __APPLE__
217
- #error "Never use CLOCK_MONOTONIC for steady_clock::now on Apple platforms"
218
- #endif
219
-
220
158
steady_clock::time_point
221
159
steady_clock::now () _NOEXCEPT
222
160
{
@@ -227,7 +165,7 @@ steady_clock::now() _NOEXCEPT
227
165
}
228
166
229
167
#else
230
- #error "Monotonic clock not implemented"
168
+ # error "Monotonic clock not implemented"
231
169
#endif
232
170
233
171
#endif // !_LIBCPP_HAS_NO_MONOTONIC_CLOCK
0 commit comments