diff options
| -rw-r--r-- | src/core/core.cpp | 65 | ||||
| -rw-r--r-- | src/core/core.h | 10 | ||||
| -rw-r--r-- | src/core/core_timing.cpp | 29 | ||||
| -rw-r--r-- | src/core/core_timing.h | 7 | ||||
| -rw-r--r-- | src/tests/core/core_timing.cpp | 3 | ||||
| -rw-r--r-- | src/yuzu/bootmanager.cpp | 4 | ||||
| -rw-r--r-- | src/yuzu/main.cpp | 1 | ||||
| -rw-r--r-- | src/yuzu_cmd/yuzu.cpp | 4 |
8 files changed, 65 insertions, 58 deletions
diff --git a/src/core/core.cpp b/src/core/core.cpp index 1deeee154..2c4c0dbe4 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp | |||
| @@ -133,6 +133,30 @@ struct System::Impl { | |||
| 133 | : kernel{system}, fs_controller{system}, memory{system}, hid_core{}, room_network{}, | 133 | : kernel{system}, fs_controller{system}, memory{system}, hid_core{}, room_network{}, |
| 134 | cpu_manager{system}, reporter{system}, applet_manager{system}, time_manager{system} {} | 134 | cpu_manager{system}, reporter{system}, applet_manager{system}, time_manager{system} {} |
| 135 | 135 | ||
| 136 | void Initialize(System& system) { | ||
| 137 | device_memory = std::make_unique<Core::DeviceMemory>(); | ||
| 138 | |||
| 139 | is_multicore = Settings::values.use_multi_core.GetValue(); | ||
| 140 | |||
| 141 | core_timing.SetMulticore(is_multicore); | ||
| 142 | core_timing.Initialize([&system]() { system.RegisterHostThread(); }); | ||
| 143 | |||
| 144 | const auto posix_time = std::chrono::system_clock::now().time_since_epoch(); | ||
| 145 | const auto current_time = | ||
| 146 | std::chrono::duration_cast<std::chrono::seconds>(posix_time).count(); | ||
| 147 | Settings::values.custom_rtc_differential = | ||
| 148 | Settings::values.custom_rtc.value_or(current_time) - current_time; | ||
| 149 | |||
| 150 | // Create a default fs if one doesn't already exist. | ||
| 151 | if (virtual_filesystem == nullptr) | ||
| 152 | virtual_filesystem = std::make_shared<FileSys::RealVfsFilesystem>(); | ||
| 153 | if (content_provider == nullptr) | ||
| 154 | content_provider = std::make_unique<FileSys::ContentProviderUnion>(); | ||
| 155 | |||
| 156 | // Create default implementations of applets if one is not provided. | ||
| 157 | applet_manager.SetDefaultAppletsIfMissing(); | ||
| 158 | } | ||
| 159 | |||
| 136 | SystemResultStatus Run() { | 160 | SystemResultStatus Run() { |
| 137 | std::unique_lock<std::mutex> lk(suspend_guard); | 161 | std::unique_lock<std::mutex> lk(suspend_guard); |
| 138 | status = SystemResultStatus::Success; | 162 | status = SystemResultStatus::Success; |
| @@ -178,37 +202,17 @@ struct System::Impl { | |||
| 178 | debugger = std::make_unique<Debugger>(system, port); | 202 | debugger = std::make_unique<Debugger>(system, port); |
| 179 | } | 203 | } |
| 180 | 204 | ||
| 181 | SystemResultStatus Init(System& system, Frontend::EmuWindow& emu_window) { | 205 | SystemResultStatus SetupForMainProcess(System& system, Frontend::EmuWindow& emu_window) { |
| 182 | LOG_DEBUG(Core, "initialized OK"); | 206 | LOG_DEBUG(Core, "initialized OK"); |
| 183 | 207 | ||
| 184 | device_memory = std::make_unique<Core::DeviceMemory>(); | ||
| 185 | |||
| 186 | is_multicore = Settings::values.use_multi_core.GetValue(); | ||
| 187 | is_async_gpu = Settings::values.use_asynchronous_gpu_emulation.GetValue(); | 208 | is_async_gpu = Settings::values.use_asynchronous_gpu_emulation.GetValue(); |
| 188 | 209 | ||
| 189 | kernel.SetMulticore(is_multicore); | 210 | kernel.SetMulticore(is_multicore); |
| 190 | cpu_manager.SetMulticore(is_multicore); | 211 | cpu_manager.SetMulticore(is_multicore); |
| 191 | cpu_manager.SetAsyncGpu(is_async_gpu); | 212 | cpu_manager.SetAsyncGpu(is_async_gpu); |
| 192 | core_timing.SetMulticore(is_multicore); | ||
| 193 | 213 | ||
| 194 | kernel.Initialize(); | 214 | kernel.Initialize(); |
| 195 | cpu_manager.Initialize(); | 215 | cpu_manager.Initialize(); |
| 196 | core_timing.Initialize([&system]() { system.RegisterHostThread(); }); | ||
| 197 | |||
| 198 | const auto posix_time = std::chrono::system_clock::now().time_since_epoch(); | ||
| 199 | const auto current_time = | ||
| 200 | std::chrono::duration_cast<std::chrono::seconds>(posix_time).count(); | ||
| 201 | Settings::values.custom_rtc_differential = | ||
| 202 | Settings::values.custom_rtc.value_or(current_time) - current_time; | ||
| 203 | |||
| 204 | // Create a default fs if one doesn't already exist. | ||
| 205 | if (virtual_filesystem == nullptr) | ||
| 206 | virtual_filesystem = std::make_shared<FileSys::RealVfsFilesystem>(); | ||
| 207 | if (content_provider == nullptr) | ||
| 208 | content_provider = std::make_unique<FileSys::ContentProviderUnion>(); | ||
| 209 | |||
| 210 | /// Create default implementations of applets if one is not provided. | ||
| 211 | applet_manager.SetDefaultAppletsIfMissing(); | ||
| 212 | 216 | ||
| 213 | /// Reset all glue registrations | 217 | /// Reset all glue registrations |
| 214 | arp_manager.ResetAll(); | 218 | arp_manager.ResetAll(); |
| @@ -253,11 +257,11 @@ struct System::Impl { | |||
| 253 | return SystemResultStatus::ErrorGetLoader; | 257 | return SystemResultStatus::ErrorGetLoader; |
| 254 | } | 258 | } |
| 255 | 259 | ||
| 256 | SystemResultStatus init_result{Init(system, emu_window)}; | 260 | SystemResultStatus init_result{SetupForMainProcess(system, emu_window)}; |
| 257 | if (init_result != SystemResultStatus::Success) { | 261 | if (init_result != SystemResultStatus::Success) { |
| 258 | LOG_CRITICAL(Core, "Failed to initialize system (Error {})!", | 262 | LOG_CRITICAL(Core, "Failed to initialize system (Error {})!", |
| 259 | static_cast<int>(init_result)); | 263 | static_cast<int>(init_result)); |
| 260 | Shutdown(); | 264 | ShutdownMainProcess(); |
| 261 | return init_result; | 265 | return init_result; |
| 262 | } | 266 | } |
| 263 | 267 | ||
| @@ -276,7 +280,7 @@ struct System::Impl { | |||
| 276 | const auto [load_result, load_parameters] = app_loader->Load(*main_process, system); | 280 | const auto [load_result, load_parameters] = app_loader->Load(*main_process, system); |
| 277 | if (load_result != Loader::ResultStatus::Success) { | 281 | if (load_result != Loader::ResultStatus::Success) { |
| 278 | LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", load_result); | 282 | LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", load_result); |
| 279 | Shutdown(); | 283 | ShutdownMainProcess(); |
| 280 | 284 | ||
| 281 | return static_cast<SystemResultStatus>( | 285 | return static_cast<SystemResultStatus>( |
| 282 | static_cast<u32>(SystemResultStatus::ErrorLoader) + static_cast<u32>(load_result)); | 286 | static_cast<u32>(SystemResultStatus::ErrorLoader) + static_cast<u32>(load_result)); |
| @@ -335,7 +339,7 @@ struct System::Impl { | |||
| 335 | return status; | 339 | return status; |
| 336 | } | 340 | } |
| 337 | 341 | ||
| 338 | void Shutdown() { | 342 | void ShutdownMainProcess() { |
| 339 | SetShuttingDown(true); | 343 | SetShuttingDown(true); |
| 340 | 344 | ||
| 341 | // Log last frame performance stats if game was loded | 345 | // Log last frame performance stats if game was loded |
| @@ -369,7 +373,7 @@ struct System::Impl { | |||
| 369 | cheat_engine.reset(); | 373 | cheat_engine.reset(); |
| 370 | telemetry_session.reset(); | 374 | telemetry_session.reset(); |
| 371 | time_manager.Shutdown(); | 375 | time_manager.Shutdown(); |
| 372 | core_timing.Shutdown(); | 376 | core_timing.ClearPendingEvents(); |
| 373 | app_loader.reset(); | 377 | app_loader.reset(); |
| 374 | audio_core.reset(); | 378 | audio_core.reset(); |
| 375 | gpu_core.reset(); | 379 | gpu_core.reset(); |
| @@ -377,7 +381,6 @@ struct System::Impl { | |||
| 377 | perf_stats.reset(); | 381 | perf_stats.reset(); |
| 378 | kernel.Shutdown(); | 382 | kernel.Shutdown(); |
| 379 | memory.Reset(); | 383 | memory.Reset(); |
| 380 | applet_manager.ClearAll(); | ||
| 381 | 384 | ||
| 382 | if (auto room_member = room_network.GetRoomMember().lock()) { | 385 | if (auto room_member = room_network.GetRoomMember().lock()) { |
| 383 | Network::GameInfo game_info{}; | 386 | Network::GameInfo game_info{}; |
| @@ -520,6 +523,10 @@ const CpuManager& System::GetCpuManager() const { | |||
| 520 | return impl->cpu_manager; | 523 | return impl->cpu_manager; |
| 521 | } | 524 | } |
| 522 | 525 | ||
| 526 | void System::Initialize() { | ||
| 527 | impl->Initialize(*this); | ||
| 528 | } | ||
| 529 | |||
| 523 | SystemResultStatus System::Run() { | 530 | SystemResultStatus System::Run() { |
| 524 | return impl->Run(); | 531 | return impl->Run(); |
| 525 | } | 532 | } |
| @@ -540,8 +547,8 @@ void System::InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size) { | |||
| 540 | impl->kernel.InvalidateCpuInstructionCacheRange(addr, size); | 547 | impl->kernel.InvalidateCpuInstructionCacheRange(addr, size); |
| 541 | } | 548 | } |
| 542 | 549 | ||
| 543 | void System::Shutdown() { | 550 | void System::ShutdownMainProcess() { |
| 544 | impl->Shutdown(); | 551 | impl->ShutdownMainProcess(); |
| 545 | } | 552 | } |
| 546 | 553 | ||
| 547 | bool System::IsShuttingDown() const { | 554 | bool System::IsShuttingDown() const { |
diff --git a/src/core/core.h b/src/core/core.h index 7843cc8ad..4ebedffd9 100644 --- a/src/core/core.h +++ b/src/core/core.h | |||
| @@ -143,6 +143,12 @@ public: | |||
| 143 | System& operator=(System&&) = delete; | 143 | System& operator=(System&&) = delete; |
| 144 | 144 | ||
| 145 | /** | 145 | /** |
| 146 | * Initializes the system | ||
| 147 | * This function will initialize core functionaility used for system emulation | ||
| 148 | */ | ||
| 149 | void Initialize(); | ||
| 150 | |||
| 151 | /** | ||
| 146 | * Run the OS and Application | 152 | * Run the OS and Application |
| 147 | * This function will start emulation and run the relevant devices | 153 | * This function will start emulation and run the relevant devices |
| 148 | */ | 154 | */ |
| @@ -166,8 +172,8 @@ public: | |||
| 166 | 172 | ||
| 167 | void InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size); | 173 | void InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size); |
| 168 | 174 | ||
| 169 | /// Shutdown the emulated system. | 175 | /// Shutdown the main emulated process. |
| 170 | void Shutdown(); | 176 | void ShutdownMainProcess(); |
| 171 | 177 | ||
| 172 | /// Check if the core is shutting down. | 178 | /// Check if the core is shutting down. |
| 173 | [[nodiscard]] bool IsShuttingDown() const; | 179 | [[nodiscard]] bool IsShuttingDown() const; |
diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp index 2678ce532..2afb2696c 100644 --- a/src/core/core_timing.cpp +++ b/src/core/core_timing.cpp | |||
| @@ -40,7 +40,17 @@ struct CoreTiming::Event { | |||
| 40 | CoreTiming::CoreTiming() | 40 | CoreTiming::CoreTiming() |
| 41 | : clock{Common::CreateBestMatchingClock(Hardware::BASE_CLOCK_RATE, Hardware::CNTFREQ)} {} | 41 | : clock{Common::CreateBestMatchingClock(Hardware::BASE_CLOCK_RATE, Hardware::CNTFREQ)} {} |
| 42 | 42 | ||
| 43 | CoreTiming::~CoreTiming() = default; | 43 | CoreTiming::~CoreTiming() { |
| 44 | paused = true; | ||
| 45 | shutting_down = true; | ||
| 46 | pause_event.Set(); | ||
| 47 | event.Set(); | ||
| 48 | if (timer_thread) { | ||
| 49 | timer_thread->join(); | ||
| 50 | } | ||
| 51 | timer_thread.reset(); | ||
| 52 | has_started = false; | ||
| 53 | } | ||
| 44 | 54 | ||
| 45 | void CoreTiming::ThreadEntry(CoreTiming& instance) { | 55 | void CoreTiming::ThreadEntry(CoreTiming& instance) { |
| 46 | constexpr char name[] = "HostTiming"; | 56 | constexpr char name[] = "HostTiming"; |
| @@ -65,17 +75,8 @@ void CoreTiming::Initialize(std::function<void()>&& on_thread_init_) { | |||
| 65 | } | 75 | } |
| 66 | } | 76 | } |
| 67 | 77 | ||
| 68 | void CoreTiming::Shutdown() { | 78 | void CoreTiming::ClearPendingEvents() { |
| 69 | paused = true; | 79 | event_queue.clear(); |
| 70 | shutting_down = true; | ||
| 71 | pause_event.Set(); | ||
| 72 | event.Set(); | ||
| 73 | if (timer_thread) { | ||
| 74 | timer_thread->join(); | ||
| 75 | } | ||
| 76 | ClearPendingEvents(); | ||
| 77 | timer_thread.reset(); | ||
| 78 | has_started = false; | ||
| 79 | } | 80 | } |
| 80 | 81 | ||
| 81 | void CoreTiming::Pause(bool is_paused) { | 82 | void CoreTiming::Pause(bool is_paused) { |
| @@ -196,10 +197,6 @@ u64 CoreTiming::GetClockTicks() const { | |||
| 196 | return CpuCyclesToClockCycles(ticks); | 197 | return CpuCyclesToClockCycles(ticks); |
| 197 | } | 198 | } |
| 198 | 199 | ||
| 199 | void CoreTiming::ClearPendingEvents() { | ||
| 200 | event_queue.clear(); | ||
| 201 | } | ||
| 202 | |||
| 203 | void CoreTiming::RemoveEvent(const std::shared_ptr<EventType>& event_type) { | 200 | void CoreTiming::RemoveEvent(const std::shared_ptr<EventType>& event_type) { |
| 204 | std::scoped_lock lock{basic_lock}; | 201 | std::scoped_lock lock{basic_lock}; |
| 205 | 202 | ||
diff --git a/src/core/core_timing.h b/src/core/core_timing.h index 3259397b2..7996b529f 100644 --- a/src/core/core_timing.h +++ b/src/core/core_timing.h | |||
| @@ -61,8 +61,8 @@ public: | |||
| 61 | /// required to end slice - 1 and start slice 0 before the first cycle of code is executed. | 61 | /// required to end slice - 1 and start slice 0 before the first cycle of code is executed. |
| 62 | void Initialize(std::function<void()>&& on_thread_init_); | 62 | void Initialize(std::function<void()>&& on_thread_init_); |
| 63 | 63 | ||
| 64 | /// Tears down all timing related functionality. | 64 | /// Clear all pending events. This should ONLY be done on exit. |
| 65 | void Shutdown(); | 65 | void ClearPendingEvents(); |
| 66 | 66 | ||
| 67 | /// Sets if emulation is multicore or single core, must be set before Initialize | 67 | /// Sets if emulation is multicore or single core, must be set before Initialize |
| 68 | void SetMulticore(bool is_multicore_) { | 68 | void SetMulticore(bool is_multicore_) { |
| @@ -136,9 +136,6 @@ public: | |||
| 136 | private: | 136 | private: |
| 137 | struct Event; | 137 | struct Event; |
| 138 | 138 | ||
| 139 | /// Clear all pending events. This should ONLY be done on exit. | ||
| 140 | void ClearPendingEvents(); | ||
| 141 | |||
| 142 | static void ThreadEntry(CoreTiming& instance); | 139 | static void ThreadEntry(CoreTiming& instance); |
| 143 | void ThreadLoop(); | 140 | void ThreadLoop(); |
| 144 | 141 | ||
diff --git a/src/tests/core/core_timing.cpp b/src/tests/core/core_timing.cpp index 7c432a63c..284b2ae66 100644 --- a/src/tests/core/core_timing.cpp +++ b/src/tests/core/core_timing.cpp | |||
| @@ -40,9 +40,6 @@ struct ScopeInit final { | |||
| 40 | core_timing.SetMulticore(true); | 40 | core_timing.SetMulticore(true); |
| 41 | core_timing.Initialize([]() {}); | 41 | core_timing.Initialize([]() {}); |
| 42 | } | 42 | } |
| 43 | ~ScopeInit() { | ||
| 44 | core_timing.Shutdown(); | ||
| 45 | } | ||
| 46 | 43 | ||
| 47 | Core::Timing::CoreTiming core_timing; | 44 | Core::Timing::CoreTiming core_timing; |
| 48 | }; | 45 | }; |
diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp index 24251247d..6acfb7b06 100644 --- a/src/yuzu/bootmanager.cpp +++ b/src/yuzu/bootmanager.cpp | |||
| @@ -120,8 +120,8 @@ void EmuThread::run() { | |||
| 120 | } | 120 | } |
| 121 | } | 121 | } |
| 122 | 122 | ||
| 123 | // Shutdown the core emulation | 123 | // Shutdown the main emulated process |
| 124 | system.Shutdown(); | 124 | system.ShutdownMainProcess(); |
| 125 | 125 | ||
| 126 | #if MICROPROFILE_ENABLED | 126 | #if MICROPROFILE_ENABLED |
| 127 | MicroProfileOnThreadExit(); | 127 | MicroProfileOnThreadExit(); |
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index a94624be6..501c34255 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp | |||
| @@ -294,6 +294,7 @@ GMainWindow::GMainWindow(std::unique_ptr<Config> config_, bool has_broken_vulkan | |||
| 294 | #ifdef __linux__ | 294 | #ifdef __linux__ |
| 295 | SetupSigInterrupts(); | 295 | SetupSigInterrupts(); |
| 296 | #endif | 296 | #endif |
| 297 | system->Initialize(); | ||
| 297 | 298 | ||
| 298 | Common::Log::Initialize(); | 299 | Common::Log::Initialize(); |
| 299 | LoadTranslation(); | 300 | LoadTranslation(); |
diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp index 3a0f33cba..e16f79eb4 100644 --- a/src/yuzu_cmd/yuzu.cpp +++ b/src/yuzu_cmd/yuzu.cpp | |||
| @@ -302,6 +302,8 @@ int main(int argc, char** argv) { | |||
| 302 | } | 302 | } |
| 303 | 303 | ||
| 304 | Core::System system{}; | 304 | Core::System system{}; |
| 305 | system.Initialize(); | ||
| 306 | |||
| 305 | InputCommon::InputSubsystem input_subsystem{}; | 307 | InputCommon::InputSubsystem input_subsystem{}; |
| 306 | 308 | ||
| 307 | // Apply the command line arguments | 309 | // Apply the command line arguments |
| @@ -392,7 +394,7 @@ int main(int argc, char** argv) { | |||
| 392 | } | 394 | } |
| 393 | system.DetachDebugger(); | 395 | system.DetachDebugger(); |
| 394 | void(system.Pause()); | 396 | void(system.Pause()); |
| 395 | system.Shutdown(); | 397 | system.ShutdownMainProcess(); |
| 396 | 398 | ||
| 397 | detached_tasks.WaitForAllTasks(); | 399 | detached_tasks.WaitForAllTasks(); |
| 398 | return 0; | 400 | return 0; |