diff options
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/page_table.h | 12 | ||||
-rw-r--r-- | src/common/settings.cpp | 3 | ||||
-rw-r--r-- | src/common/time_zone.cpp | 47 | ||||
-rw-r--r-- | src/common/wall_clock.cpp | 4 |
4 files changed, 29 insertions, 37 deletions
diff --git a/src/common/page_table.h b/src/common/page_table.h index fec8378f3..e653d52ad 100644 --- a/src/common/page_table.h +++ b/src/common/page_table.h @@ -51,7 +51,7 @@ struct PageTable { class PageInfo { public: /// Returns the page pointer - [[nodiscard]] u8* Pointer() const noexcept { + [[nodiscard]] uintptr_t Pointer() const noexcept { return ExtractPointer(raw.load(std::memory_order_relaxed)); } @@ -61,7 +61,7 @@ struct PageTable { } /// Returns the page pointer and attribute pair, extracted from the same atomic read - [[nodiscard]] std::pair<u8*, PageType> PointerType() const noexcept { + [[nodiscard]] std::pair<uintptr_t, PageType> PointerType() const noexcept { const uintptr_t non_atomic_raw = raw.load(std::memory_order_relaxed); return {ExtractPointer(non_atomic_raw), ExtractType(non_atomic_raw)}; } @@ -73,13 +73,13 @@ struct PageTable { } /// Write a page pointer and type pair atomically - void Store(u8* pointer, PageType type) noexcept { - raw.store(reinterpret_cast<uintptr_t>(pointer) | static_cast<uintptr_t>(type)); + void Store(uintptr_t pointer, PageType type) noexcept { + raw.store(pointer | static_cast<uintptr_t>(type)); } /// Unpack a pointer from a page info raw representation - [[nodiscard]] static u8* ExtractPointer(uintptr_t raw) noexcept { - return reinterpret_cast<u8*>(raw & (~uintptr_t{0} << ATTRIBUTE_BITS)); + [[nodiscard]] static uintptr_t ExtractPointer(uintptr_t raw) noexcept { + return raw & (~uintptr_t{0} << ATTRIBUTE_BITS); } /// Unpack a page type from a page info raw representation diff --git a/src/common/settings.cpp b/src/common/settings.cpp index 491adc30e..15fd2e222 100644 --- a/src/common/settings.cpp +++ b/src/common/settings.cpp @@ -72,7 +72,8 @@ std::string GetTimeZoneString(TimeZone time_zone) { std::string location_name; if (time_zone_index == 0) { // Auto -#if __cpp_lib_chrono >= 201907L +#if __cpp_lib_chrono >= 201907L && !defined(MINGW) + // Disabled for MinGW -- tzdb always returns Etc/UTC try { const struct std::chrono::tzdb& time_zone_data = std::chrono::get_tzdb(); const std::chrono::time_zone* current_zone = time_zone_data.current_zone(); diff --git a/src/common/time_zone.cpp b/src/common/time_zone.cpp index d8d7896c6..69e728a9d 100644 --- a/src/common/time_zone.cpp +++ b/src/common/time_zone.cpp @@ -4,13 +4,13 @@ #include <chrono> #include <exception> #include <iomanip> +#include <map> #include <sstream> #include <stdexcept> #include <fmt/chrono.h> #include <fmt/core.h> #include "common/logging/log.h" -#include "common/settings.h" #include "common/time_zone.h" namespace Common::TimeZone { @@ -33,32 +33,29 @@ std::string GetDefaultTimeZone() { return "GMT"; } -static std::string GetOsTimeZoneOffset() { - const std::time_t t{std::time(nullptr)}; - const std::tm tm{*std::localtime(&t)}; - - return fmt::format("{:%z}", tm); -} - -static int ConvertOsTimeZoneOffsetToInt(const std::string& timezone) { - try { - return std::stoi(timezone); - } catch (const std::invalid_argument&) { - LOG_CRITICAL(Common, "invalid_argument with {}!", timezone); - return 0; - } catch (const std::out_of_range&) { - LOG_CRITICAL(Common, "out_of_range with {}!", timezone); - return 0; - } +// Results are not comparable to seconds since Epoch +static std::time_t TmSpecToSeconds(const struct std::tm& spec) { + const int year = spec.tm_year - 1; // Years up to now + const int leap_years = year / 4 - year / 100; + std::time_t cumulative = spec.tm_year; + cumulative = cumulative * 365 + leap_years + spec.tm_yday; // Years to days + cumulative = cumulative * 24 + spec.tm_hour; // Days to hours + cumulative = cumulative * 60 + spec.tm_min; // Hours to minutes + cumulative = cumulative * 60 + spec.tm_sec; // Minutes to seconds + return cumulative; } std::chrono::seconds GetCurrentOffsetSeconds() { - const int offset{ConvertOsTimeZoneOffsetToInt(GetOsTimeZoneOffset())}; + const std::time_t t{std::time(nullptr)}; + const std::tm local{*std::localtime(&t)}; + const std::tm gmt{*std::gmtime(&t)}; - int seconds{(offset / 100) * 60 * 60}; // Convert hour component to seconds - seconds += (offset % 100) * 60; // Convert minute component to seconds + // gmt_seconds is a different offset than time(nullptr) + const auto gmt_seconds = TmSpecToSeconds(gmt); + const auto local_seconds = TmSpecToSeconds(local); + const auto seconds_offset = local_seconds - gmt_seconds; - return std::chrono::seconds{seconds}; + return std::chrono::seconds{seconds_offset}; } // Key is [Hours * 100 + Minutes], multiplied by 100 if DST @@ -71,11 +68,6 @@ const static std::map<s64, const char*> off_timezones = { }; std::string FindSystemTimeZone() { -#if defined(MINGW) - // MinGW has broken strftime -- https://sourceforge.net/p/mingw-w64/bugs/793/ - // e.g. fmt::format("{:%z}") -- returns "Eastern Daylight Time" when it should be "-0400" - return timezones[0]; -#else const s64 seconds = static_cast<s64>(GetCurrentOffsetSeconds().count()); const s64 minutes = seconds / 60; @@ -97,7 +89,6 @@ std::string FindSystemTimeZone() { } } return fmt::format("Etc/GMT{:s}{:d}", hours > 0 ? "-" : "+", std::abs(hours)); -#endif } } // namespace Common::TimeZone diff --git a/src/common/wall_clock.cpp b/src/common/wall_clock.cpp index dc0dcbd68..71e15ab4c 100644 --- a/src/common/wall_clock.cpp +++ b/src/common/wall_clock.cpp @@ -56,12 +56,12 @@ std::unique_ptr<WallClock> CreateOptimalClock() { #ifdef ARCHITECTURE_x86_64 const auto& caps = GetCPUCaps(); - if (caps.invariant_tsc && caps.tsc_frequency >= WallClock::GPUTickFreq) { + if (caps.invariant_tsc && caps.tsc_frequency >= std::nano::den) { return std::make_unique<X64::NativeClock>(caps.tsc_frequency); } else { // Fallback to StandardWallClock if the hardware TSC // - Is not invariant - // - Is not more precise than GPUTickFreq + // - Is not more precise than 1 GHz (1ns resolution) return std::make_unique<StandardWallClock>(); } #else |