KernelState::TerminateTitle - Release the global lock in smaller regions / No need for an argument specifying if called from guest

This commit is contained in:
Dr. Chat 2015-12-16 12:00:35 -06:00 committed by Ben Vanik
parent 366f91e191
commit f5237d486a
3 changed files with 13 additions and 14 deletions

View File

@ -333,7 +333,7 @@ object_ref<UserModule> KernelState::LoadUserModule(const char* raw_name,
return module; return module;
} }
void KernelState::TerminateTitle(bool from_guest_thread) { void KernelState::TerminateTitle() {
XELOGD("KernelState::TerminateTitle"); XELOGD("KernelState::TerminateTitle");
auto global_lock = global_critical_region_.Acquire(); auto global_lock = global_critical_region_.Acquire();
@ -352,13 +352,11 @@ void KernelState::TerminateTitle(bool from_guest_thread) {
*/ */
// Kill all guest threads. // 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();) { for (auto it = threads_by_id_.begin(); it != threads_by_id_.end();) {
if (it->second->is_guest_thread()) { if (it->second->is_guest_thread()) {
auto thread = it->second; auto thread = it->second;
if (from_guest_thread && XThread::IsInThread(thread)) { if (XThread::IsInThread(thread)) {
// Don't terminate ourselves. // Don't terminate ourselves.
++it; ++it;
continue; continue;
@ -372,8 +370,10 @@ void KernelState::TerminateTitle(bool from_guest_thread) {
thread->thread()->Suspend(); thread->thread()->Suspend();
} }
global_lock.unlock();
thread->StepToSafePoint(); thread->StepToSafePoint();
thread->Terminate(0); thread->Terminate(0);
global_lock.lock();
} }
// Erase it from the thread list. // Erase it from the thread list.
@ -382,7 +382,6 @@ void KernelState::TerminateTitle(bool from_guest_thread) {
++it; ++it;
} }
} }
global_lock.lock();
// Third: Unload all user modules (including the executable) // Third: Unload all user modules (including the executable)
for (int i = 0; i < user_modules_.size(); i++) { for (int i = 0; i < user_modules_.size(); i++) {
@ -399,13 +398,11 @@ void KernelState::TerminateTitle(bool from_guest_thread) {
// Unregister all notify listeners. // Unregister all notify listeners.
notify_listeners_.clear(); notify_listeners_.clear();
if (from_guest_thread) { if (XThread::IsInThread()) {
threads_by_id_.erase(XThread::GetCurrentThread()->thread_id()); threads_by_id_.erase(XThread::GetCurrentThread()->thread_id());
// Now commit suicide (using Terminate, because we can't call into guest // Now commit suicide (using Terminate, because we can't call into guest
// code anymore) // code anymore)
// Also, manually invoke the lock guard's destructor, because Terminate
// does not return.
global_lock.unlock(); global_lock.unlock();
XThread::GetCurrentThread()->Terminate(0); XThread::GetCurrentThread()->Terminate(0);
} }
@ -624,7 +621,7 @@ bool KernelState::Save(ByteStream* stream) {
} }
if (!thread->Save(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--; num_threads--;
} }
} }

View File

@ -143,7 +143,7 @@ class KernelState {
// Terminates a title: Unloads all modules, and kills all guest threads. // Terminates a title: Unloads all modules, and kills all guest threads.
// This DOES NOT RETURN if called from a guest thread! // This DOES NOT RETURN if called from a guest thread!
void TerminateTitle(bool from_guest_thread = false); void TerminateTitle();
void RegisterThread(XThread* thread); void RegisterThread(XThread* thread);
void UnregisterThread(XThread* thread); void UnregisterThread(XThread* thread);

View File

@ -147,7 +147,9 @@ void XamLoaderLaunchTitle(lpstring_t raw_name, dword_t flags) {
loader_data.launch_flags = flags; loader_data.launch_flags = flags;
// Translate the launch path to a full path. // 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 name = xe::find_name_from_path(std::string(raw_name));
std::string path(raw_name); std::string path(raw_name);
if (name == std::string(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. // This function does not return.
kernel_state()->TerminateTitle(true); kernel_state()->TerminateTitle();
} }
DECLARE_XAM_EXPORT(XamLoaderLaunchTitle, ExportTag::kSketchy); DECLARE_XAM_EXPORT(XamLoaderLaunchTitle, ExportTag::kSketchy);
void XamLoaderTerminateTitle() { void XamLoaderTerminateTitle() {
// This function does not return. // This function does not return.
kernel_state()->TerminateTitle(true); kernel_state()->TerminateTitle();
} }
DECLARE_XAM_EXPORT(XamLoaderTerminateTitle, ExportTag::kSketchy); DECLARE_XAM_EXPORT(XamLoaderTerminateTitle, ExportTag::kSketchy);