diff options
-rw-r--r-- | src/core/hle/service/time/interface.h | 2 | ||||
-rw-r--r-- | src/core/hle/service/time/time.cpp | 3 | ||||
-rw-r--r-- | src/core/hle/service/time/time.h | 1 | ||||
-rw-r--r-- | src/core/hle/service/time/time_sharedmemory.cpp | 47 | ||||
-rw-r--r-- | src/core/hle/service/time/time_sharedmemory.h | 37 |
5 files changed, 53 insertions, 37 deletions
diff --git a/src/core/hle/service/time/interface.h b/src/core/hle/service/time/interface.h index 407acf960..bdf0883e2 100644 --- a/src/core/hle/service/time/interface.h +++ b/src/core/hle/service/time/interface.h @@ -7,7 +7,9 @@ #include "core/hle/service/time/time.h" namespace Service::Time { + class SharedMemory; + class Time final : public Module::Interface { public: explicit Time(std::shared_ptr<Module> time, std::shared_ptr<SharedMemory> shared_memory, diff --git a/src/core/hle/service/time/time.cpp b/src/core/hle/service/time/time.cpp index 10a7e6c97..ae6446204 100644 --- a/src/core/hle/service/time/time.cpp +++ b/src/core/hle/service/time/time.cpp @@ -418,7 +418,8 @@ void InstallInterfaces(Core::System& system) { std::make_shared<Time>(time, shared_mem, "time:a")->InstallAsService(system.ServiceManager()); std::make_shared<Time>(time, shared_mem, "time:s")->InstallAsService(system.ServiceManager()); - std::make_shared<Time>(time, shared_mem, "time:u")->InstallAsService(system.ServiceManager()); + std::make_shared<Time>(std::move(time), shared_mem, "time:u") + ->InstallAsService(system.ServiceManager()); } } // namespace Service::Time diff --git a/src/core/hle/service/time/time.h b/src/core/hle/service/time/time.h index 6a05a22b9..e0708f856 100644 --- a/src/core/hle/service/time/time.h +++ b/src/core/hle/service/time/time.h @@ -9,6 +9,7 @@ #include "core/hle/service/service.h" namespace Service::Time { + class SharedMemory; struct LocationName { diff --git a/src/core/hle/service/time/time_sharedmemory.cpp b/src/core/hle/service/time/time_sharedmemory.cpp index 650c9af7a..bfc81b83c 100644 --- a/src/core/hle/service/time/time_sharedmemory.cpp +++ b/src/core/hle/service/time/time_sharedmemory.cpp @@ -1,4 +1,4 @@ -// Copyright 2018 yuzu emulator team +// Copyright 2019 yuzu emulator team // Licensed under GPLv2 or any later version // Refer to the license.txt file included. @@ -6,15 +6,17 @@ #include "core/hle/service/time/time_sharedmemory.h" namespace Service::Time { +const std::size_t SHARED_MEMORY_SIZE = 0x1000; SharedMemory::SharedMemory(Core::System& system) : system(system) { shared_memory_holder = Kernel::SharedMemory::Create( system.Kernel(), nullptr, SHARED_MEMORY_SIZE, Kernel::MemoryPermission::ReadWrite, Kernel::MemoryPermission::Read, 0, Kernel::MemoryRegion::BASE, "Time:SharedMemory"); - shared_memory_format = reinterpret_cast<Format*>(shared_memory_holder->GetPointer()); - shared_memory_format->format_version = - 14; // Seems static from 1.0.0 -> 8.1.0. Specific games seem to check this value and crash - // if it's set to anything else + + // Seems static from 1.0.0 -> 8.1.0. Specific games seem to check this value and crash + // if it's set to anything else + shared_memory_format.format_version = 14; + std::memcpy(shared_memory_holder->GetPointer(), &shared_memory_format, sizeof(Format)); } SharedMemory::~SharedMemory() = default; @@ -24,36 +26,43 @@ Kernel::SharedPtr<Kernel::SharedMemory> SharedMemory::GetSharedMemoryHolder() co } void SharedMemory::SetStandardSteadyClockTimepoint(const SteadyClockTimePoint& timepoint) { - shared_memory_format->standard_steady_clock_timepoint.StoreData(timepoint); + shared_memory_format.standard_steady_clock_timepoint.StoreData( + shared_memory_holder->GetPointer(), timepoint); } void SharedMemory::SetStandardLocalSystemClockContext(const SystemClockContext& context) { - shared_memory_format->standard_local_system_clock_context.StoreData(context); + shared_memory_format.standard_local_system_clock_context.StoreData( + shared_memory_holder->GetPointer(), context); } void SharedMemory::SetStandardNetworkSystemClockContext(const SystemClockContext& context) { - shared_memory_format->standard_network_system_clock_context.StoreData(context); + shared_memory_format.standard_network_system_clock_context.StoreData( + shared_memory_holder->GetPointer(), context); } -void SharedMemory::SetStandardUserSystemClockAutomaticCorrectionEnabled(const bool enabled) { - shared_memory_format->standard_user_system_clock_automatic_correction.StoreData(enabled ? 1 - : 0); +void SharedMemory::SetStandardUserSystemClockAutomaticCorrectionEnabled(bool enabled) { + shared_memory_format.standard_user_system_clock_automatic_correction.StoreData( + shared_memory_holder->GetPointer(), enabled); } -SteadyClockTimePoint SharedMemory::GetStandardSteadyClockTimepoint() const { - return shared_memory_format->standard_steady_clock_timepoint.ReadData(); +SteadyClockTimePoint SharedMemory::GetStandardSteadyClockTimepoint() { + return shared_memory_format.standard_steady_clock_timepoint.ReadData( + shared_memory_holder->GetPointer()); } -SystemClockContext SharedMemory::GetStandardLocalSystemClockContext() const { - return shared_memory_format->standard_local_system_clock_context.ReadData(); +SystemClockContext SharedMemory::GetStandardLocalSystemClockContext() { + return shared_memory_format.standard_local_system_clock_context.ReadData( + shared_memory_holder->GetPointer()); } -SystemClockContext SharedMemory::GetStandardNetworkSystemClockContext() const { - return shared_memory_format->standard_network_system_clock_context.ReadData(); +SystemClockContext SharedMemory::GetStandardNetworkSystemClockContext() { + return shared_memory_format.standard_network_system_clock_context.ReadData( + shared_memory_holder->GetPointer()); } -bool SharedMemory::GetStandardUserSystemClockAutomaticCorrectionEnabled() const { - return shared_memory_format->standard_user_system_clock_automatic_correction.ReadData() > 0; +bool SharedMemory::GetStandardUserSystemClockAutomaticCorrectionEnabled() { + return shared_memory_format.standard_user_system_clock_automatic_correction.ReadData( + shared_memory_holder->GetPointer()); } } // namespace Service::Time diff --git a/src/core/hle/service/time/time_sharedmemory.h b/src/core/hle/service/time/time_sharedmemory.h index ab536005c..cb8253541 100644 --- a/src/core/hle/service/time/time_sharedmemory.h +++ b/src/core/hle/service/time/time_sharedmemory.h @@ -1,4 +1,4 @@ -// Copyright 2018 yuzu emulator team +// Copyright 2019 yuzu emulator team // Licensed under GPLv2 or any later version // Refer to the license.txt file included. @@ -11,7 +11,7 @@ namespace Service::Time { class SharedMemory { public: - SharedMemory(Core::System& system); + explicit SharedMemory(Core::System& system); ~SharedMemory(); // Return the shared memory handle @@ -21,51 +21,54 @@ public: void SetStandardSteadyClockTimepoint(const SteadyClockTimePoint& timepoint); void SetStandardLocalSystemClockContext(const SystemClockContext& context); void SetStandardNetworkSystemClockContext(const SystemClockContext& context); - void SetStandardUserSystemClockAutomaticCorrectionEnabled(const bool enabled); + void SetStandardUserSystemClockAutomaticCorrectionEnabled(bool enabled); // Pull from memory barriers in the shared memory - SteadyClockTimePoint GetStandardSteadyClockTimepoint() const; - SystemClockContext GetStandardLocalSystemClockContext() const; - SystemClockContext GetStandardNetworkSystemClockContext() const; - bool GetStandardUserSystemClockAutomaticCorrectionEnabled() const; + SteadyClockTimePoint GetStandardSteadyClockTimepoint(); + SystemClockContext GetStandardLocalSystemClockContext(); + SystemClockContext GetStandardNetworkSystemClockContext(); + bool GetStandardUserSystemClockAutomaticCorrectionEnabled(); // TODO(ogniK): We have to properly simulate memory barriers, how are we going to do this? - template <typename T> + template <typename T, std::size_t Offset> struct MemoryBarrier { + static_assert(std::is_trivially_constructible_v<T>, "T must be trivially constructable"); u32_le read_attempt{}; - T data[2]{}; + std::array<T, 2> data{}; // These are not actually memory barriers at the moment as we don't have multicore and all // HLE is mutexed. This will need to properly be implemented when we start updating the time // points on threads. As of right now, we'll be updated both values synchronously and just // incrementing the read_attempt to indicate that we waited. - void StoreData(T data_to_store) { + void StoreData(u8* shared_memory, T data_to_store) { + std::memcpy(this, shared_memory + Offset, sizeof(*this)); read_attempt++; data[read_attempt & 1] = data_to_store; + std::memcpy(shared_memory + Offset, this, sizeof(*this)); } // For reading we're just going to read the last stored value. If there was no value stored // it will just end up reading an empty value as intended. - T ReadData() const { + T ReadData(u8* shared_memory) { + std::memcpy(this, shared_memory + Offset, sizeof(*this)); return data[(read_attempt - 1) & 1]; } }; // Shared memory format struct Format { - MemoryBarrier<SteadyClockTimePoint> standard_steady_clock_timepoint; - MemoryBarrier<SystemClockContext> standard_local_system_clock_context; - MemoryBarrier<SystemClockContext> standard_network_system_clock_context; - MemoryBarrier<u8> standard_user_system_clock_automatic_correction; + MemoryBarrier<SteadyClockTimePoint, 0x0> standard_steady_clock_timepoint; + MemoryBarrier<SystemClockContext, 0x38> standard_local_system_clock_context; + MemoryBarrier<SystemClockContext, 0x80> standard_network_system_clock_context; + MemoryBarrier<bool, 0xc8> standard_user_system_clock_automatic_correction; u32_le format_version; }; static_assert(sizeof(Format) == 0xd8, "Format is an invalid size"); private: - const std::size_t SHARED_MEMORY_SIZE = 0x1000; Kernel::SharedPtr<Kernel::SharedMemory> shared_memory_holder{}; Core::System& system; - Format* shared_memory_format; + Format shared_memory_format{}; }; } // namespace Service::Time |