From f5237d486a3edaae4b45459405226d7c8523d257 Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Wed, 16 Dec 2015 12:00:35 -0600 Subject: [PATCH] KernelState::TerminateTitle - Release the global lock in smaller regions / No need for an argument specifying if called from guest --- src/xenia/kernel/kernel_state.cc | 17 +++++++---------- src/xenia/kernel/kernel_state.h | 2 +- src/xenia/kernel/xam/xam_info.cc | 8 +++++--- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/xenia/kernel/kernel_state.cc b/src/xenia/kernel/kernel_state.cc index 4f934470d..68f8d00af 100644 --- a/src/xenia/kernel/kernel_state.cc +++ b/src/xenia/kernel/kernel_state.cc @@ -333,7 +333,7 @@ object_ref KernelState::LoadUserModule(const char* raw_name, return module; } -void KernelState::TerminateTitle(bool from_guest_thread) { +void KernelState::TerminateTitle() { XELOGD("KernelState::TerminateTitle"); auto global_lock = global_critical_region_.Acquire(); @@ -352,13 +352,11 @@ void KernelState::TerminateTitle(bool from_guest_thread) { */ // Kill all guest threads. - // Need to not be holding the lock to do this. - global_lock.unlock(); for (auto it = threads_by_id_.begin(); it != threads_by_id_.end();) { if (it->second->is_guest_thread()) { auto thread = it->second; - if (from_guest_thread && XThread::IsInThread(thread)) { + if (XThread::IsInThread(thread)) { // Don't terminate ourselves. ++it; continue; @@ -372,8 +370,10 @@ void KernelState::TerminateTitle(bool from_guest_thread) { thread->thread()->Suspend(); } + global_lock.unlock(); thread->StepToSafePoint(); thread->Terminate(0); + global_lock.lock(); } // Erase it from the thread list. @@ -382,13 +382,12 @@ void KernelState::TerminateTitle(bool from_guest_thread) { ++it; } } - global_lock.lock(); // Third: Unload all user modules (including the executable) for (int i = 0; i < user_modules_.size(); i++) { X_STATUS status = user_modules_[i]->Unload(); assert_true(XSUCCEEDED(status)); - + object_table_.RemoveHandle(user_modules_[i]->handle()); } user_modules_.clear(); @@ -399,13 +398,11 @@ void KernelState::TerminateTitle(bool from_guest_thread) { // Unregister all notify listeners. notify_listeners_.clear(); - if (from_guest_thread) { + if (XThread::IsInThread()) { threads_by_id_.erase(XThread::GetCurrentThread()->thread_id()); // Now commit suicide (using Terminate, because we can't call into guest // code anymore) - // Also, manually invoke the lock guard's destructor, because Terminate - // does not return. global_lock.unlock(); XThread::GetCurrentThread()->Terminate(0); } @@ -624,7 +621,7 @@ bool KernelState::Save(ByteStream* stream) { } if (!thread->Save(stream)) { - XELOGD("Did not save thread \"%s\"", thread->name().c_str()); + XELOGD("Failed to save thread \"%s\"", thread->name().c_str()); num_threads--; } } diff --git a/src/xenia/kernel/kernel_state.h b/src/xenia/kernel/kernel_state.h index f730968c9..aa59cba6b 100644 --- a/src/xenia/kernel/kernel_state.h +++ b/src/xenia/kernel/kernel_state.h @@ -143,7 +143,7 @@ class KernelState { // Terminates a title: Unloads all modules, and kills all guest threads. // This DOES NOT RETURN if called from a guest thread! - void TerminateTitle(bool from_guest_thread = false); + void TerminateTitle(); void RegisterThread(XThread* thread); void UnregisterThread(XThread* thread); diff --git a/src/xenia/kernel/xam/xam_info.cc b/src/xenia/kernel/xam/xam_info.cc index 447391ef4..9d5673e34 100644 --- a/src/xenia/kernel/xam/xam_info.cc +++ b/src/xenia/kernel/xam/xam_info.cc @@ -147,7 +147,9 @@ void XamLoaderLaunchTitle(lpstring_t raw_name, dword_t flags) { loader_data.launch_flags = flags; // Translate the launch path to a full path. - if (raw_name) { + if (raw_name && raw_name.value() == "") { + loader_data.launch_path = "game:\\default.xex"; + } else if (raw_name) { std::string name = xe::find_name_from_path(std::string(raw_name)); std::string path(raw_name); if (name == std::string(raw_name)) { @@ -162,13 +164,13 @@ void XamLoaderLaunchTitle(lpstring_t raw_name, dword_t flags) { } // This function does not return. - kernel_state()->TerminateTitle(true); + kernel_state()->TerminateTitle(); } DECLARE_XAM_EXPORT(XamLoaderLaunchTitle, ExportTag::kSketchy); void XamLoaderTerminateTitle() { // This function does not return. - kernel_state()->TerminateTitle(true); + kernel_state()->TerminateTitle(); } DECLARE_XAM_EXPORT(XamLoaderTerminateTitle, ExportTag::kSketchy);