Fix TimeUTCMicros resolution on Windows
making it return actual microseconds instead of being limited to
millisecond resolution.
This uses GetSystemTimeAsFileTime
https://learn.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsystemtimeasfiletime
which returns a timestamp in multiples of 100ns since January 1st 1601.
BUG=webrtc:15212
Change-Id: I293868d8f683289a9dbcf6eccb910bd9c6694e57
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/306440
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Commit-Queue: Philipp Hancke <phancke@microsoft.com>
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#40360}
diff --git a/rtc_base/time_utils.cc b/rtc_base/time_utils.cc
index 7843453..9f112e4 100644
--- a/rtc_base/time_utils.cc
+++ b/rtc_base/time_utils.cc
@@ -14,17 +14,27 @@
#include <sys/time.h>
#endif
-#if defined(WEBRTC_WIN)
-#include <sys/timeb.h>
-#endif
-
#include "rtc_base/checks.h"
#include "rtc_base/numerics/safe_conversions.h"
#include "rtc_base/system_time.h"
#include "rtc_base/time_utils.h"
+#if defined(WEBRTC_WIN)
+#include "rtc_base/win32.h"
+#endif
+#if defined(WEBRTC_WIN)
+#include <minwinbase.h>
+#endif
namespace rtc {
+#if defined(WEBRTC_WIN) || defined(WINUWP)
+// FileTime (January 1st 1601) to Unix time (January 1st 1970)
+// offset in units of 100ns.
+static constexpr uint64_t kFileTimeToUnixTimeEpochOffset =
+ 116444736000000000ULL;
+static constexpr uint64_t kFileTimeToMicroSeconds = 10LL;
+#endif
+
ClockInterface* g_clock = nullptr;
ClockInterface* SetClockForTesting(ClockInterface* clock) {
@@ -115,8 +125,6 @@
}
private:
- static constexpr uint64_t kFileTimeToUnixTimeEpochOffset =
- 116444736000000000ULL;
static constexpr uint64_t kNTPTimeToUnixTimeEpochOffset = 2208988800000L;
// The number of nanoseconds since unix system epoch
@@ -231,13 +239,15 @@
// Convert from second (1.0) and microsecond (1e-6).
return (static_cast<int64_t>(time.tv_sec) * rtc::kNumMicrosecsPerSec +
time.tv_usec);
-
#elif defined(WEBRTC_WIN)
- struct _timeb time;
- _ftime(&time);
- // Convert from second (1.0) and milliseconds (1e-3).
- return (static_cast<int64_t>(time.time) * rtc::kNumMicrosecsPerSec +
- static_cast<int64_t>(time.millitm) * rtc::kNumMicrosecsPerMillisec);
+ FILETIME ft;
+ // This will give us system file in UTC format in multiples of 100ns.
+ GetSystemTimeAsFileTime(&ft);
+ LARGE_INTEGER li;
+ li.HighPart = ft.dwHighDateTime;
+ li.LowPart = ft.dwLowDateTime;
+ return (li.QuadPart - kFileTimeToUnixTimeEpochOffset) /
+ kFileTimeToMicroSeconds;
#endif
}