diff --git a/FlexASIO/log.cpp b/FlexASIO/log.cpp index c7b32006..678fb1ee 100644 --- a/FlexASIO/log.cpp +++ b/FlexASIO/log.cpp @@ -14,6 +14,29 @@ namespace flexasio { namespace { + template struct FunctionPointerFunctor { + template auto operator()(Args&&... args) { + return functionPointer(std::forward(args)...); + } + }; + + using Library = std::unique_ptr, FunctionPointerFunctor>; + + // On systems that support GetSystemTimePreciseAsFileTime() (i.e. Windows 8 and greater), use that. + // Otherwise, fall back to GetSystemTimeAsFileTime(). + // See https://github.com/dechamps/FlexASIO/issues/15 + decltype(GetSystemTimeAsFileTime)* GetSystemTimeAsFileTimeFunction() { + static const auto function = [] { + static const Library library(LoadLibraryA("kernel32.dll")); + if (library != nullptr) { + const auto function = GetProcAddress(library.get(), "GetSystemTimePreciseAsFileTime"); + if (function != nullptr) return reinterpret_cast(function); + } + return GetSystemTimeAsFileTime; + }(); + return function; + } + int64_t FileTimeToTenthsOfUs(const FILETIME filetime) { ULARGE_INTEGER integer; integer.LowPart = filetime.dwLowDateTime; @@ -104,6 +127,7 @@ namespace flexasio { Output(const std::filesystem::path& path) : stream(path, std::ios::app | std::ios::out) { Log(this) << "Logfile opened"; + Log(this) << "Log time source: " << ((GetSystemTimeAsFileTimeFunction() == GetSystemTimeAsFileTime) ? "GetSystemTimeAsFileTime" : "GetSystemTimePreciseAsFileTime"); } ~Output() { @@ -127,7 +151,7 @@ namespace flexasio { stream.emplace(); FILETIME now; - GetSystemTimePreciseAsFileTime(&now); + GetSystemTimeAsFileTimeFunction()(&now); *stream << FormatFiletimeISO8601(now) << " " << GetCurrentProcessId() << " " << GetCurrentThreadId() << " "; }