47 #if defined _MSV_VER || defined _MSC_VER
51 #if defined(__APPLE__)
52 #include <mach/clock.h>
53 #include <mach/mach.h>
54 #endif // defined(__APPLE__)
68 #define HAS_CLOCK_GETTIME (_POSIX_C_SOURCE >= 199309L)
84 const Time TIME_MAX(std::numeric_limits<uint32_t>::max(), 999999999);
109 #if HAS_CLOCK_GETTIME
111 clock_gettime(CLOCK_REALTIME, &
start);
112 if (
start.tv_sec < 0 ||
start.tv_sec > UINT_MAX)
113 throw std::runtime_error(
"Timespec is out of dual 32-bit range");
117 struct timeval timeofday;
118 gettimeofday(&timeofday, NULL);
119 if (timeofday.tv_sec < 0 || timeofday.tv_sec > UINT_MAX)
120 throw std::runtime_error(
"Timeofday is out of dual signed 32-bit range");
121 sec = timeofday.tv_sec;
122 nsec = timeofday.tv_usec * 1000;
135 static LARGE_INTEGER cpu_freq, init_cpu_time;
136 static uint32_t start_sec = 0;
137 static uint32_t start_nsec = 0;
138 if ((start_sec == 0) && (start_nsec == 0))
140 QueryPerformanceFrequency(&cpu_freq);
141 if (cpu_freq.QuadPart == 0) {
144 QueryPerformanceCounter(&init_cpu_time);
147 GetSystemTimeAsFileTime(&ft);
148 LARGE_INTEGER start_li;
149 start_li.LowPart = ft.dwLowDateTime;
150 start_li.HighPart = ft.dwHighDateTime;
154 start_li.QuadPart -= 116444736000000000Ui64;
156 start_li.QuadPart -= 116444736000000000ULL;
158 int64_t start_sec64 = start_li.QuadPart / 10000000;
159 if (start_sec64 < 0 || start_sec64 > UINT_MAX)
160 throw std::runtime_error(
"SystemTime is out of dual 32-bit range");
161 start_sec = (uint32_t)start_sec64;
162 start_nsec = (start_li.LowPart % 10000000) * 100;
164 LARGE_INTEGER cur_time;
165 QueryPerformanceCounter(&cur_time);
166 LARGE_INTEGER delta_cpu_time;
167 delta_cpu_time.QuadPart = cur_time.QuadPart - init_cpu_time.QuadPart;
170 double d_delta_cpu_time = delta_cpu_time.QuadPart / (double)cpu_freq.QuadPart;
171 uint32_t delta_sec = (uint32_t)floor(d_delta_cpu_time);
172 uint32_t delta_nsec = (uint32_t)std::round((d_delta_cpu_time - delta_sec) * 1e9);
174 int64_t sec_sum = (int64_t)start_sec + (int64_t)delta_sec;
175 int64_t nsec_sum = (int64_t)start_nsec + (int64_t)delta_nsec;
189 #if defined(__APPLE__)
193 host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cclock);
194 clock_get_time(cclock, &mts);
195 mach_port_deallocate(mach_task_self(), cclock);
196 start.tv_sec = mts.tv_sec;
197 start.tv_nsec = mts.tv_nsec;
198 #else // defined(__APPLE__)
200 clock_gettime(CLOCK_MONOTONIC, &
start);
201 #endif // defined(__APPLE__)
205 static LARGE_INTEGER cpu_frequency, performance_count;
211 QueryPerformanceFrequency(&cpu_frequency);
212 if (cpu_frequency.QuadPart == 0) {
215 QueryPerformanceCounter(&performance_count);
216 double steady_time = performance_count.QuadPart / (double)cpu_frequency.QuadPart;
217 int64_t steady_sec = floor(steady_time);
218 int64_t steady_nsec = std::round((steady_time - steady_sec) * 1e9);
235 LARGE_INTEGER sleepTime;
236 sleepTime.QuadPart = -
237 static_cast<int64_t
>(
sec) * 10000000LL -
238 static_cast<int64_t
>(
nsec) / 100LL;
240 timer = CreateWaitableTimer(NULL, TRUE, NULL);
246 if (!SetWaitableTimer(timer, &sleepTime, 0, NULL, NULL, 0))
251 if (WaitForSingleObject(timer, INFINITE) != WAIT_OBJECT_0)
258 return nanosleep(&req, NULL);
273 timespec rem = { 0, 0 };
274 while (nanosleep(&req, &rem) && !
g_stopped)
396 s << rhs.sec <<
"." << std::setw(9) << std::setfill(
'0') << rhs.nsec;
405 if (rhs.sec >= 0 || rhs.nsec == 0)
407 s << rhs.sec <<
"." << std::setw(9) << std::setfill(
'0') << rhs.nsec;
411 s << (rhs.sec == -1 ?
"-" :
"") << (rhs.sec + 1) <<
"." << std::setw(9) << std::setfill(
'0') << (1000000000 - rhs.nsec);
456 bool SteadyTime::sleepUntil(
const SteadyTime& end)
459 if (d > WallDuration(0))
472 std::this_thread::sleep_for(std::chrono::microseconds(
sec * 1000000+
nsec/1000));
515 std::ostream &
operator<<(std::ostream& os,
const WallTime &rhs)
519 s << rhs.sec <<
"." << std::setw(9) << std::setfill(
'0') << rhs.nsec;
525 std::ostream &
operator<<(std::ostream& os,
const SteadyTime &rhs)
527 boost::io::ios_all_saver
s(os);
528 os << rhs.sec <<
"." << std::setw(9) << std::setfill(
'0') << rhs.nsec;
548 std::ostream &
operator<<(std::ostream& os,
const WallDuration& rhs)
552 if (rhs.sec >= 0 || rhs.nsec == 0)
554 s << rhs.sec <<
"." << std::setw(9) << std::setfill(
'0') << rhs.nsec;
558 s << (rhs.sec == -1 ?
"-" :
"") << (rhs.sec + 1) <<
"." << std::setw(9) << std::setfill(
'0') << (1000000000 - rhs.nsec);
571 uint64_t nsec_part =
nsec % 1000000000UL;
572 uint64_t sec_part =
nsec / 1000000000UL;
574 if (
sec + sec_part > UINT_MAX)
575 throw std::runtime_error(std::string(
"normalizeSecNSec: time (") + std::to_string(
sec) +
"," + std::to_string(
nsec) +
") is out of dual 32-bit range");
584 uint64_t nsec64 =
nsec;
588 sec = (uint32_t)sec64;
589 nsec = (uint32_t)nsec64;
594 int64_t nsec_part =
nsec % 1000000000L;
595 int64_t sec_part =
sec +
nsec / 1000000000L;
598 nsec_part += 1000000000L;
602 if (sec_part < 0 || sec_part > UINT_MAX)
603 throw std::runtime_error(std::string(
"normalizeSecNSecUnsigned: time (") + std::to_string(
sec) +
"," + std::to_string(
nsec) +
") is out of dual 32-bit range");