49 #if defined(__APPLE__)
50 #include <mach/clock.h>
51 #include <mach/mach.h>
52 #endif // defined(__APPLE__)
60 #include <boost/thread/mutex.hpp>
61 #include <boost/io/ios_state.hpp>
62 #include <boost/date_time/posix_time/ptime.hpp>
70 #define HAS_CLOCK_GETTIME (_POSIX_C_SOURCE >= 199309L)
83 const Duration
DURATION_MAX(std::numeric_limits<int32_t>::max(), 999999999);
84 const Duration
DURATION_MIN(std::numeric_limits<int32_t>::min(), 0);
144 #if HAS_CLOCK_GETTIME
146 clock_gettime(CLOCK_REALTIME, &start);
147 if (start.tv_sec < 0 || start.tv_sec > std::numeric_limits<uint32_t>::max())
148 throw std::runtime_error(
"Timespec is out of dual 32-bit range");
150 nsec = start.tv_nsec;
152 struct timeval timeofday;
153 gettimeofday(&timeofday,NULL);
154 if (timeofday.tv_sec < 0 || timeofday.tv_sec > std::numeric_limits<uint32_t>::max())
155 throw std::runtime_error(
"Timeofday is out of dual signed 32-bit range");
156 sec = timeofday.tv_sec;
157 nsec = timeofday.tv_usec * 1000;
161 uint64_t now_ns = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
165 sec = (uint32_t)now_s;
166 nsec = (uint32_t)now_ns;
174 #if defined(__APPLE__)
178 host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cclock);
179 clock_get_time(cclock, &mts);
180 mach_port_deallocate(mach_task_self(), cclock);
181 start.tv_sec = mts.tv_sec;
182 start.tv_nsec = mts.tv_nsec;
183 #else // defined(__APPLE__)
185 clock_gettime(CLOCK_MONOTONIC, &start);
186 #endif // defined(__APPLE__)
188 nsec = start.tv_nsec;
191 uint64_t now_ns = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
195 sec = (uint32_t)now_s;
196 nsec = (uint32_t)now_ns;
211 std::this_thread::sleep_for(std::chrono::nanoseconds(
static_cast<int64_t
>(sec * 1e9 + nsec)));
214 timespec req = { sec, nsec };
215 return nanosleep(&req, NULL);
229 timespec req = { sec, nsec };
230 timespec rem = {0, 0};
231 while (nanosleep(&req, &rem) && !
g_stopped)
331 boost::posix_time::time_duration diff = t - boost::posix_time::from_time_t(0);
338 int64_t sec64 = d.total_seconds();
339 if (sec64 < 0 || sec64 > std::numeric_limits<uint32_t>::max())
340 throw std::runtime_error(
"time_duration is out of dual 32-bit range");
341 t.
sec = (uint32_t)sec64;
342 #if defined(BOOST_DATE_TIME_HAS_NANOSECONDS)
343 t.
nsec = d.fractional_seconds();
345 t.
nsec = d.fractional_seconds()*1000;
352 boost::io::ios_all_saver s(os);
353 os << rhs.
sec <<
"." << std::setw(9) << std::setfill(
'0') << rhs.
nsec;
357 std::ostream&
operator<<(std::ostream& os,
const Duration& rhs)
359 boost::io::ios_all_saver s(os);
360 if (rhs.sec >= 0 || rhs.nsec == 0)
362 os << rhs.sec <<
"." << std::setw(9) << std::setfill(
'0') << rhs.nsec;
366 os << (rhs.sec == -1 ?
"-" :
"") << (rhs.sec + 1) <<
"." << std::setw(9) << std::setfill(
'0') << (1000000000 - rhs.nsec);
430 Time end = start + *
this;
438 const uint32_t sleep_nsec = (
sec != 0) ? 1000000 : (std::min)(1000000,
nsec/10);
463 std::ostream &
operator<<(std::ostream& os,
const WallTime &rhs)
465 boost::io::ios_all_saver s(os);
466 os << rhs.sec <<
"." << std::setw(9) << std::setfill(
'0') << rhs.nsec;
470 std::ostream &
operator<<(std::ostream& os,
const SteadyTime &rhs)
472 boost::io::ios_all_saver s(os);
473 os << rhs.sec <<
"." << std::setw(9) << std::setfill(
'0') << rhs.nsec;
495 boost::io::ios_all_saver s(os);
496 if (rhs.
sec >= 0 || rhs.
nsec == 0)
498 os << rhs.
sec <<
"." << std::setw(9) << std::setfill(
'0') << rhs.
nsec;
502 os << (rhs.
sec == -1 ?
"-" :
"") << (rhs.
sec + 1) <<
"." << std::setw(9) << std::setfill(
'0') << (1000000000 - rhs.
nsec);
514 uint64_t nsec_part = nsec % 1000000000UL;
515 uint64_t sec_part = nsec / 1000000000UL;
517 if (sec + sec_part > std::numeric_limits<uint32_t>::max())
518 throw std::runtime_error(
"Time is out of dual 32-bit range");
526 uint64_t sec64 = sec;
527 uint64_t nsec64 = nsec;
531 sec = (uint32_t)sec64;
532 nsec = (uint32_t)nsec64;
537 int64_t nsec_part = nsec % 1000000000L;
538 int64_t sec_part = sec + nsec / 1000000000L;
541 nsec_part += 1000000000L;
545 if (sec_part < 0 || sec_part > std::numeric_limits<uint32_t>::max())
546 throw std::runtime_error(
"Time is out of dual 32-bit range");
552 template class TimeBase<Time, Duration>;
553 template class TimeBase<WallTime, WallDuration>;
554 template class TimeBase<SteadyTime, WallDuration>;