Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #8950 from jordan-woyak/double-time-fix
Common/Timer: Fix integer underflow in Timer::GetDoubleTime for dates before ~2008.
  • Loading branch information
JMC47 committed Jul 12, 2020
2 parents 4d36f6a + eab0786 commit 3c70fb7
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 31 deletions.
40 changes: 10 additions & 30 deletions Source/Core/Common/Timer.cpp
Expand Up @@ -4,7 +4,7 @@

#include "Common/Timer.h"

#include <ctime>
#include <chrono>
#include <string>

#ifdef _WIN32
Expand Down Expand Up @@ -233,37 +233,17 @@ std::string Timer::GetTimeFormatted()
// Returns a timestamp with decimals for precise time comparisons
double Timer::GetDoubleTime()
{
#ifdef _WIN32
struct timeb tp;
(void)::ftime(&tp);
#elif defined __APPLE__
struct timeval t;
(void)gettimeofday(&t, nullptr);
#else
struct timespec t;
(void)clock_gettime(CLOCK_MONOTONIC, &t);
#endif
// Get continuous timestamp
u64 TmpSeconds = Common::Timer::GetTimeSinceJan1970();
// FYI: std::chrono::system_clock epoch is not required to be 1970 until c++20.
// We will however assume time_t IS unix time.
using Clock = std::chrono::system_clock;

// Remove a few years. We only really want enough seconds to make
// sure that we are detecting actual actions, perhaps 60 seconds is
// enough really, but I leave a year of seconds anyway, in case the
// user's clock is incorrect or something like that.
TmpSeconds = TmpSeconds - DOUBLE_TIME_OFFSET;

// Make a smaller integer that fits in the double
u32 Seconds = (u32)TmpSeconds;
#ifdef _WIN32
double ms = tp.millitm / 1000.0 / 1000.0;
#elif defined __APPLE__
double ms = t.tv_usec / 1000000.0;
#else
double ms = t.tv_nsec / 1000000000.0;
#endif
double TmpTime = Seconds + ms;
// TODO: Use this on switch to c++20:
// const auto since_epoch = Clock::now().time_since_epoch();
const auto unix_epoch = Clock::from_time_t({});
const auto since_epoch = Clock::now() - unix_epoch;

return TmpTime;
const auto since_double_time_epoch = since_epoch - std::chrono::seconds(DOUBLE_TIME_OFFSET);
return std::chrono::duration_cast<std::chrono::duration<double>>(since_double_time_epoch).count();
}

// Formats a timestamp from GetDoubleTime() into a date and time string
Expand Down
2 changes: 1 addition & 1 deletion Source/Core/Common/Timer.h
Expand Up @@ -41,7 +41,7 @@ class Timer

// Arbitrarily chosen value (38 years) that is subtracted in GetDoubleTime()
// to increase sub-second precision of the resulting double timestamp
static const int DOUBLE_TIME_OFFSET = (38 * 365 * 24 * 60 * 60);
static constexpr int DOUBLE_TIME_OFFSET = (38 * 365 * 24 * 60 * 60);

private:
u64 m_LastTime;
Expand Down

0 comments on commit 3c70fb7

Please sign in to comment.