fixed an accuracy issue with timer classes on mac

This commit is contained in:
Arvid Norberg 2009-04-25 21:51:34 +00:00
parent b324d4a190
commit f7ebd88bec
2 changed files with 30 additions and 44 deletions

View File

@ -131,10 +131,10 @@ namespace libtorrent
struct ptime struct ptime
{ {
ptime() {} ptime() {}
explicit ptime(boost::int64_t t): time(t) {} explicit ptime(boost::uint64_t t): time(t) {}
ptime& operator+=(time_duration rhs) { time += rhs.diff; return *this; } ptime& operator+=(time_duration rhs) { time += rhs.diff; return *this; }
ptime& operator-=(time_duration rhs) { time -= rhs.diff; return *this; } ptime& operator-=(time_duration rhs) { time -= rhs.diff; return *this; }
boost::int64_t time; boost::uint64_t time;
}; };
inline bool operator>(ptime lhs, ptime rhs) inline bool operator>(ptime lhs, ptime rhs)
@ -160,7 +160,7 @@ namespace libtorrent
ptime time_now(); ptime time_now();
inline ptime min_time() { return ptime(0); } inline ptime min_time() { return ptime(0); }
inline ptime max_time() { return ptime((std::numeric_limits<boost::int64_t>::max)()); } inline ptime max_time() { return ptime((std::numeric_limits<boost::uint64_t>::max)()); }
int total_seconds(time_duration td); int total_seconds(time_duration td);
int total_milliseconds(time_duration td); int total_milliseconds(time_duration td);
boost::int64_t total_microseconds(time_duration td); boost::int64_t total_microseconds(time_duration td);
@ -204,71 +204,50 @@ namespace asio
namespace libtorrent namespace libtorrent
{ {
namespace aux
{
inline boost::int64_t absolutetime_to_microseconds(boost::int64_t at)
{
static mach_timebase_info_data_t timebase_info = {0,0};
if (timebase_info.denom == 0)
mach_timebase_info(&timebase_info);
// make sure we don't overflow
TORRENT_ASSERT((at >= 0 && at >= at / 1000 * timebase_info.numer / timebase_info.denom)
|| (at < 0 && at < at / 1000 * timebase_info.numer / timebase_info.denom));
return at / 1000 * timebase_info.numer / timebase_info.denom;
}
inline boost::int64_t microseconds_to_absolutetime(boost::int64_t ms)
{
static mach_timebase_info_data_t timebase_info = {0,0};
if (timebase_info.denom == 0)
{
mach_timebase_info(&timebase_info);
TORRENT_ASSERT(timebase_info.numer > 0);
TORRENT_ASSERT(timebase_info.denom > 0);
}
// make sure we don't overflow
TORRENT_ASSERT((ms >= 0 && ms <= ms * timebase_info.denom / timebase_info.numer * 1000)
|| (ms < 0 && ms > ms * timebase_info.denom / timebase_info.numer * 1000));
return ms * timebase_info.denom / timebase_info.numer * 1000;
}
}
inline int total_seconds(time_duration td) inline int total_seconds(time_duration td)
{ {
return aux::absolutetime_to_microseconds(td.diff) return td.diff / 1000000;
/ 1000000;
} }
inline int total_milliseconds(time_duration td) inline int total_milliseconds(time_duration td)
{ {
return aux::absolutetime_to_microseconds(td.diff) return td.diff / 1000;
/ 1000;
} }
inline boost::int64_t total_microseconds(time_duration td) inline boost::int64_t total_microseconds(time_duration td)
{ {
return aux::absolutetime_to_microseconds(td.diff); return td.diff;
} }
inline ptime time_now() { return ptime(mach_absolute_time()); } inline ptime time_now()
{
static mach_timebase_info_data_t timebase_info = {0,0};
if (timebase_info.denom == 0)
mach_timebase_info(&timebase_info);
boost::uint64_t at = mach_absolute_time();
// make sure we don't overflow
TORRENT_ASSERT((at >= 0 && at >= at / 1000 * timebase_info.numer / timebase_info.denom)
|| (at < 0 && at < at / 1000 * timebase_info.numer / timebase_info.denom));
return ptime(at / 1000 * timebase_info.numer / timebase_info.denom);
}
inline time_duration microsec(boost::int64_t s) inline time_duration microsec(boost::int64_t s)
{ {
return time_duration(aux::microseconds_to_absolutetime(s)); return time_duration(s);
} }
inline time_duration milliseconds(boost::int64_t s) inline time_duration milliseconds(boost::int64_t s)
{ {
return time_duration(aux::microseconds_to_absolutetime(s * 1000)); return time_duration(s * 1000);
} }
inline time_duration seconds(boost::int64_t s) inline time_duration seconds(boost::int64_t s)
{ {
return time_duration(aux::microseconds_to_absolutetime(s * 1000000)); return time_duration(s * 1000000);
} }
inline time_duration minutes(boost::int64_t s) inline time_duration minutes(boost::int64_t s)
{ {
return time_duration(aux::microseconds_to_absolutetime(s * 1000000 * 60)); return time_duration(s * 1000000 * 60);
} }
inline time_duration hours(boost::int64_t s) inline time_duration hours(boost::int64_t s)
{ {
return time_duration(aux::microseconds_to_absolutetime(s * 1000000 * 60 * 60)); return time_duration(s * 1000000 * 60 * 60);
} }
} }
@ -386,7 +365,7 @@ namespace libtorrent
{ {
timespec ts; timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts); clock_gettime(CLOCK_MONOTONIC, &ts);
return ptime(boost::int64_t(ts.tv_sec) * 1000000 + ts.tv_nsec / 1000); return ptime(boost::uint64_t(ts.tv_sec) * 1000000 + ts.tv_nsec / 1000);
} }
inline time_duration microsec(boost::int64_t s) inline time_duration microsec(boost::int64_t s)

View File

@ -355,6 +355,13 @@ int test_main()
{ {
using namespace libtorrent; using namespace libtorrent;
// make sure the time classes have correct semantics
TEST_CHECK(total_milliseconds(milliseconds(100)) == 100);
TEST_CHECK(total_milliseconds(milliseconds(1)) == 1);
TEST_CHECK(total_milliseconds(seconds(1)) == 1000);
// make sure the assumption we use in policy's peer list hold // make sure the assumption we use in policy's peer list hold
std::multimap<address, int> peers; std::multimap<address, int> peers;
std::multimap<address, int>::iterator i; std::multimap<address, int>::iterator i;