summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/core.cpp65
-rw-r--r--src/core/core.h10
-rw-r--r--src/core/core_timing.cpp29
-rw-r--r--src/core/core_timing.h7
-rw-r--r--src/tests/core/core_timing.cpp3
-rw-r--r--src/yuzu/bootmanager.cpp4
-rw-r--r--src/yuzu/main.cpp1
-rw-r--r--src/yuzu_cmd/yuzu.cpp4
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
526void System::Initialize() {
527 impl->Initialize(*this);
528}
529
523SystemResultStatus System::Run() { 530SystemResultStatus 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
543void System::Shutdown() { 550void System::ShutdownMainProcess() {
544 impl->Shutdown(); 551 impl->ShutdownMainProcess();
545} 552}
546 553
547bool System::IsShuttingDown() const { 554bool 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 {
40CoreTiming::CoreTiming() 40CoreTiming::CoreTiming()
41 : clock{Common::CreateBestMatchingClock(Hardware::BASE_CLOCK_RATE, Hardware::CNTFREQ)} {} 41 : clock{Common::CreateBestMatchingClock(Hardware::BASE_CLOCK_RATE, Hardware::CNTFREQ)} {}
42 42
43CoreTiming::~CoreTiming() = default; 43CoreTiming::~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
45void CoreTiming::ThreadEntry(CoreTiming& instance) { 55void 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
68void CoreTiming::Shutdown() { 78void 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
81void CoreTiming::Pause(bool is_paused) { 82void 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
199void CoreTiming::ClearPendingEvents() {
200 event_queue.clear();
201}
202
203void CoreTiming::RemoveEvent(const std::shared_ptr<EventType>& event_type) { 200void 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:
136private: 136private:
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;