From f88bf33b4fea827b124eefc8f97d8e0f2d06a2d4 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Tue, 19 May 2015 22:20:49 -0700 Subject: [PATCH] Moving threads to XHostThread and making shutdown not crash. --- src/xenia/apu/audio_system.cc | 40 +++++++------- src/xenia/apu/audio_system.h | 14 ++--- src/xenia/emulator.cc | 51 ++++++++++-------- src/xenia/emulator.h | 9 ---- src/xenia/gpu/gl4/command_processor.cc | 23 ++++---- src/xenia/gpu/gl4/command_processor.h | 12 +++-- src/xenia/gpu/gl4/gl4_gpu.cc | 4 +- src/xenia/gpu/gl4/gl4_gpu.h | 2 +- src/xenia/gpu/gl4/gl4_graphics_system.cc | 4 +- src/xenia/gpu/gl4/gl4_graphics_system.h | 2 +- src/xenia/gpu/gpu.cc | 6 +-- src/xenia/gpu/gpu.h | 4 +- src/xenia/gpu/graphics_system.cc | 5 +- src/xenia/gpu/graphics_system.h | 4 +- src/xenia/kernel/kernel_state.cc | 67 +++++++++++++----------- src/xenia/kernel/kernel_state.h | 13 ++++- src/xenia/kernel/objects/xmodule.cc | 15 ++++++ src/xenia/kernel/objects/xmodule.h | 1 + src/xenia/kernel/objects/xthread.cc | 21 ++++---- src/xenia/kernel/objects/xuser_module.cc | 8 +-- src/xenia/ui/win32/win32_control.cc | 1 + src/xenia/ui/win32/win32_loop.cc | 7 ++- 22 files changed, 175 insertions(+), 138 deletions(-) diff --git a/src/xenia/apu/audio_system.cc b/src/xenia/apu/audio_system.cc index da1d8cab2..7b980c8dd 100644 --- a/src/xenia/apu/audio_system.cc +++ b/src/xenia/apu/audio_system.cc @@ -14,8 +14,8 @@ #include "xenia/base/math.h" #include "xenia/cpu/processor.h" #include "xenia/cpu/thread_state.h" -#include "xenia/kernel/objects/xthread.h" #include "xenia/emulator.h" +#include "xenia/kernel/objects/xthread.h" #include "xenia/profiling.h" // As with normal Microsoft, there are like twelve different ways to access @@ -48,7 +48,6 @@ namespace xe { namespace apu { using namespace xe::cpu; -using namespace xe::kernel; // Size of a hardware XMA context. const uint32_t kXmaContextSize = 64; @@ -56,7 +55,7 @@ const uint32_t kXmaContextSize = 64; const uint32_t kXmaContextCount = 320; AudioSystem::AudioSystem(Emulator* emulator) - : emulator_(emulator), memory_(emulator->memory()), running_(false) { + : emulator_(emulator), memory_(emulator->memory()), worker_running_(false) { memset(clients_, 0, sizeof(clients_)); for (size_t i = 0; i < maximum_client_count_; ++i) { unused_clients_.push(i); @@ -91,22 +90,18 @@ X_STATUS AudioSystem::Setup() { } registers_.next_context = 1; - // Setup our worker thread - std::function thread_fn = [this]() { - this->ThreadStart(); + worker_running_ = true; + worker_thread_ = new kernel::XHostThread(emulator()->kernel_state(), + 128 * 1024, 0, [this]() { + this->WorkerThreadMain(); return 0; - }; - - running_ = true; - - thread_ = std::make_unique(emulator()->kernel_state(), - 128 * 1024, 0, thread_fn); - thread_->Create(); + }); + worker_thread_->Create(); return X_STATUS_SUCCESS; } -void AudioSystem::ThreadStart() { +void AudioSystem::WorkerThreadMain() { xe::threading::set_name("Audio Worker"); // Initialize driver and ringbuffer. @@ -115,7 +110,7 @@ void AudioSystem::ThreadStart() { auto processor = emulator_->processor(); // Main run loop. - while (running_) { + while (worker_running_) { auto result = WaitForMultipleObjectsEx(DWORD(xe::countof(client_wait_handles_)), client_wait_handles_, FALSE, INFINITE, FALSE); @@ -135,8 +130,8 @@ void AudioSystem::ThreadStart() { lock_.unlock(); if (client_callback) { uint64_t args[] = {client_callback_arg}; - processor->Execute(thread_->thread_state(), client_callback, args, - xe::countof(args)); + processor->Execute(worker_thread_->thread_state(), client_callback, + args, xe::countof(args)); } pumped++; index++; @@ -145,7 +140,7 @@ void AudioSystem::ThreadStart() { WAIT_OBJECT_0); } - if (!running_) { + if (!worker_running_) { break; } @@ -154,7 +149,7 @@ void AudioSystem::ThreadStart() { Sleep(500); } } - running_ = false; + worker_running_ = false; // TODO(benvanik): call module API to kill? } @@ -162,9 +157,10 @@ void AudioSystem::ThreadStart() { void AudioSystem::Initialize() {} void AudioSystem::Shutdown() { - running_ = false; - ResetEvent(client_wait_handles_[maximum_client_count_]); - thread_->Wait(0, 0, 0, NULL); + worker_running_ = false; + SetEvent(client_wait_handles_[maximum_client_count_]); + worker_thread_->Wait(0, 0, 0, nullptr); + worker_thread_->Release(); memory()->SystemHeapFree(registers_.xma_context_array_ptr); } diff --git a/src/xenia/apu/audio_system.h b/src/xenia/apu/audio_system.h index fc2f61381..125402c1f 100644 --- a/src/xenia/apu/audio_system.h +++ b/src/xenia/apu/audio_system.h @@ -13,15 +13,17 @@ #include #include #include -#include #include "xenia/emulator.h" #include "xenia/xbox.h" namespace xe { +namespace kernel { +class XHostThread; +} // namespace kernel +} // namespace xe -namespace kernel { class XHostThread; } - +namespace xe { namespace apu { class AudioDriver; @@ -59,7 +61,7 @@ class AudioSystem { virtual void Initialize(); private: - void ThreadStart(); + void WorkerThreadMain(); static uint64_t MMIOReadRegisterThunk(AudioSystem* as, uint32_t addr) { return as->ReadRegister(addr); @@ -76,8 +78,8 @@ class AudioSystem { Memory* memory_; cpu::Processor* processor_; - std::unique_ptr thread_; - std::atomic running_; + std::atomic worker_running_; + kernel::XHostThread* worker_thread_; std::mutex lock_; diff --git a/src/xenia/emulator.cc b/src/xenia/emulator.cc index a88760980..c2d2df23b 100644 --- a/src/xenia/emulator.cc +++ b/src/xenia/emulator.cc @@ -28,7 +28,6 @@ using namespace xe::apu; using namespace xe::cpu; using namespace xe::gpu; using namespace xe::hid; -using namespace xe::kernel; using namespace xe::kernel::fs; using namespace xe::ui; @@ -38,17 +37,14 @@ Emulator::Emulator(const std::wstring& command_line) Emulator::~Emulator() { // Note that we delete things in the reverse order they were initialized. - xam_.reset(); - xboxkrnl_.reset(); - kernel_state_.reset(); - - file_system_.reset(); - - input_system_.reset(); - // Give the systems time to shutdown before we delete them. graphics_system_->Shutdown(); audio_system_->Shutdown(); + + kernel_state_.reset(); + file_system_.reset(); + + input_system_.reset(); graphics_system_.reset(); audio_system_.reset(); @@ -95,7 +91,7 @@ X_STATUS Emulator::Setup() { } // Initialize the GPU. - graphics_system_ = std::move(xe::gpu::Create()); + graphics_system_ = std::move(xe::gpu::Create(this)); if (!graphics_system_) { return X_STATUS_NOT_IMPLEMENTED; } @@ -106,15 +102,6 @@ X_STATUS Emulator::Setup() { return X_STATUS_NOT_IMPLEMENTED; } - // Setup the core components. - if (!processor_->Setup()) { - return result; - } - result = graphics_system_->Setup(processor_.get(), main_window_->loop(), - main_window_.get()); - if (result) { - return result; - } result = input_system_->Setup(); if (result) { return result; @@ -124,7 +111,17 @@ X_STATUS Emulator::Setup() { file_system_ = std::make_unique(); // Shared kernel state. - kernel_state_ = std::make_unique(this); + kernel_state_ = std::make_unique(this); + + // Setup the core components. + if (!processor_->Setup()) { + return result; + } + result = graphics_system_->Setup(processor_.get(), main_window_->loop(), + main_window_.get()); + if (result) { + return result; + } result = audio_system_->Setup(); if (result) { @@ -132,8 +129,8 @@ X_STATUS Emulator::Setup() { } // HLE kernel modules. - xboxkrnl_ = std::make_unique(this, kernel_state_.get()); - xam_ = std::make_unique(this, kernel_state_.get()); + kernel_state_->LoadKernelModule(); + kernel_state_->LoadKernelModule(); return result; } @@ -192,7 +189,15 @@ X_STATUS Emulator::LaunchSTFSTitle(const std::wstring& path) { X_STATUS Emulator::CompleteLaunch(const std::wstring& path, const std::string& module_path) { - return xboxkrnl_->LaunchModule(module_path.c_str()); + auto xboxkrnl = static_cast( + kernel_state_->GetModule("xboxkrnl.exe")); + int result = xboxkrnl->LaunchModule(module_path.c_str()); + xboxkrnl->Release(); + if (result == 0) { + return X_STATUS_SUCCESS; + } else { + return X_STATUS_UNSUCCESSFUL; + } } } // namespace xe diff --git a/src/xenia/emulator.h b/src/xenia/emulator.h index 6d389a7f5..ab26d3db2 100644 --- a/src/xenia/emulator.h +++ b/src/xenia/emulator.h @@ -32,10 +32,6 @@ class GraphicsSystem; namespace hid { class InputSystem; } // namespace hid -namespace kernel { -class XamModule; -class XboxkrnlModule; -} // namespace kernel namespace ui { class MainWindow; } // namespace ui @@ -68,9 +64,6 @@ class Emulator { kernel::KernelState* kernel_state() const { return kernel_state_.get(); } - kernel::XboxkrnlModule* xboxkrnl() const { return xboxkrnl_.get(); } - kernel::XamModule* xam() const { return xam_.get(); } - X_STATUS Setup(); // TODO(benvanik): raw binary. @@ -97,8 +90,6 @@ class Emulator { std::unique_ptr file_system_; std::unique_ptr kernel_state_; - std::unique_ptr xam_; - std::unique_ptr xboxkrnl_; }; } // namespace xe diff --git a/src/xenia/gpu/gl4/command_processor.cc b/src/xenia/gpu/gl4/command_processor.cc index 7308b35e9..4ac0206b4 100644 --- a/src/xenia/gpu/gl4/command_processor.cc +++ b/src/xenia/gpu/gl4/command_processor.cc @@ -19,6 +19,8 @@ #include "xenia/gpu/sampler_info.h" #include "xenia/gpu/texture_info.h" #include "xenia/gpu/xenos.h" +#include "xenia/emulator.h" +#include "xenia/kernel/objects/xthread.h" #include "xenia/profiling.h" #include "third_party/xxhash/xxhash.h" @@ -99,12 +101,12 @@ bool CommandProcessor::Initialize(std::unique_ptr context) { context_ = std::move(context); worker_running_ = true; - worker_thread_ = std::thread([this]() { - xe::threading::set_name("GL4 Worker"); - xe::Profiler::ThreadEnter("GL4 Worker"); - WorkerMain(); - xe::Profiler::ThreadExit(); - }); + worker_thread_ = new kernel::XHostThread( + graphics_system_->emulator()->kernel_state(), 128 * 1024, 0, [this]() { + WorkerThreadMain(); + return 0; + }); + worker_thread_->Create(); return true; } @@ -114,7 +116,8 @@ void CommandProcessor::Shutdown() { worker_running_ = false; SetEvent(write_ptr_index_event_); - worker_thread_.join(); + worker_thread_->Wait(0, 0, 0, nullptr); + worker_thread_->Release(); all_pipelines_.clear(); all_shaders_.clear(); @@ -160,14 +163,16 @@ void CommandProcessor::EndTracing() { void CommandProcessor::CallInThread(std::function fn) { if (pending_fns_.empty() && - worker_thread_.get_id() == std::this_thread::get_id()) { + worker_thread_ == kernel::XThread::GetCurrentThread()) { fn(); } else { pending_fns_.push(std::move(fn)); } } -void CommandProcessor::WorkerMain() { +void CommandProcessor::WorkerThreadMain() { + xe::threading::set_name("GL4 Worker"); + context_->MakeCurrent(); if (!SetupGL()) { XEFATAL("Unable to setup command processor GL state"); diff --git a/src/xenia/gpu/gl4/command_processor.h b/src/xenia/gpu/gl4/command_processor.h index a919401ba..583fc317b 100644 --- a/src/xenia/gpu/gl4/command_processor.h +++ b/src/xenia/gpu/gl4/command_processor.h @@ -14,7 +14,6 @@ #include #include #include -#include #include #include @@ -28,6 +27,12 @@ #include "xenia/gpu/xenos.h" #include "xenia/memory.h" +namespace xe { +namespace kernel { +class XHostThread; +} // namespace kernel +} // namespace xe + namespace xe { namespace gpu { namespace gl4 { @@ -134,7 +139,7 @@ class CommandProcessor { } handles; }; - void WorkerMain(); + void WorkerThreadMain(); bool SetupGL(); void ShutdownGL(); GLuint CreateGeometryProgram(const std::string& source); @@ -226,8 +231,9 @@ class CommandProcessor { TraceState trace_state_; std::wstring trace_frame_path_; - std::thread worker_thread_; std::atomic worker_running_; + kernel::XHostThread* worker_thread_; + std::unique_ptr context_; SwapHandler swap_handler_; std::queue> pending_fns_; diff --git a/src/xenia/gpu/gl4/gl4_gpu.cc b/src/xenia/gpu/gl4/gl4_gpu.cc index c21ba0bed..955a9e17d 100644 --- a/src/xenia/gpu/gl4/gl4_gpu.cc +++ b/src/xenia/gpu/gl4/gl4_gpu.cc @@ -47,9 +47,9 @@ void InitializeIfNeeded() { void CleanupOnShutdown() {} -std::unique_ptr Create() { +std::unique_ptr Create(Emulator* emulator) { InitializeIfNeeded(); - return std::make_unique(); + return std::make_unique(emulator); } } // namespace gl4 diff --git a/src/xenia/gpu/gl4/gl4_gpu.h b/src/xenia/gpu/gl4/gl4_gpu.h index 761cc3b2d..a36429a21 100644 --- a/src/xenia/gpu/gl4/gl4_gpu.h +++ b/src/xenia/gpu/gl4/gl4_gpu.h @@ -18,7 +18,7 @@ namespace xe { namespace gpu { namespace gl4 { -std::unique_ptr Create(); +std::unique_ptr Create(Emulator* emulator); } // namespace gl4 } // namespace gpu diff --git a/src/xenia/gpu/gl4/gl4_graphics_system.cc b/src/xenia/gpu/gl4/gl4_graphics_system.cc index bd2ee1f87..f29d186d8 100644 --- a/src/xenia/gpu/gl4/gl4_graphics_system.cc +++ b/src/xenia/gpu/gl4/gl4_graphics_system.cc @@ -23,8 +23,8 @@ namespace gl4 { extern "C" GLEWContext* glewGetContext(); -GL4GraphicsSystem::GL4GraphicsSystem() - : GraphicsSystem(), timer_queue_(nullptr), vsync_timer_(nullptr) {} +GL4GraphicsSystem::GL4GraphicsSystem(Emulator* emulator) + : GraphicsSystem(emulator), timer_queue_(nullptr), vsync_timer_(nullptr) {} GL4GraphicsSystem::~GL4GraphicsSystem() = default; diff --git a/src/xenia/gpu/gl4/gl4_graphics_system.h b/src/xenia/gpu/gl4/gl4_graphics_system.h index 558af2c1c..6eeec1310 100644 --- a/src/xenia/gpu/gl4/gl4_graphics_system.h +++ b/src/xenia/gpu/gl4/gl4_graphics_system.h @@ -23,7 +23,7 @@ namespace gl4 { class GL4GraphicsSystem : public GraphicsSystem { public: - GL4GraphicsSystem(); + GL4GraphicsSystem(Emulator* emulator); ~GL4GraphicsSystem() override; X_STATUS Setup(cpu::Processor* processor, ui::PlatformLoop* target_loop, diff --git a/src/xenia/gpu/gpu.cc b/src/xenia/gpu/gpu.cc index 867a302a9..b2ebd0a11 100644 --- a/src/xenia/gpu/gpu.cc +++ b/src/xenia/gpu/gpu.cc @@ -27,14 +27,14 @@ DEFINE_bool(vsync, true, "Enable VSYNC."); namespace xe { namespace gpu { -std::unique_ptr Create() { +std::unique_ptr Create(Emulator* emulator) { if (FLAGS_gpu.compare("gl4") == 0) { - return xe::gpu::gl4::Create(); + return xe::gpu::gl4::Create(emulator); } else { // Create best available. std::unique_ptr best; - best = xe::gpu::gl4::Create(); + best = xe::gpu::gl4::Create(emulator); if (best) { return best; } diff --git a/src/xenia/gpu/gpu.h b/src/xenia/gpu/gpu.h index 912e05406..b9965229d 100644 --- a/src/xenia/gpu/gpu.h +++ b/src/xenia/gpu/gpu.h @@ -21,9 +21,7 @@ class Emulator; namespace xe { namespace gpu { -std::unique_ptr Create(); - -std::unique_ptr CreateGL4(); +std::unique_ptr Create(Emulator* emulator); } // namespace gpu } // namespace xe diff --git a/src/xenia/gpu/graphics_system.cc b/src/xenia/gpu/graphics_system.cc index 22600cc5d..09d21838d 100644 --- a/src/xenia/gpu/graphics_system.cc +++ b/src/xenia/gpu/graphics_system.cc @@ -17,8 +17,9 @@ namespace xe { namespace gpu { -GraphicsSystem::GraphicsSystem() - : memory_(nullptr), +GraphicsSystem::GraphicsSystem(Emulator* emulator) + : emulator_(emulator), + memory_(nullptr), processor_(nullptr), target_loop_(nullptr), target_window_(nullptr), diff --git a/src/xenia/gpu/graphics_system.h b/src/xenia/gpu/graphics_system.h index 8d0a74b82..3fc7a4424 100644 --- a/src/xenia/gpu/graphics_system.h +++ b/src/xenia/gpu/graphics_system.h @@ -25,6 +25,7 @@ class GraphicsSystem { public: virtual ~GraphicsSystem(); + Emulator* emulator() const { return emulator_; } Memory* memory() const { return memory_; } cpu::Processor* processor() const { return processor_; } @@ -54,8 +55,9 @@ class GraphicsSystem { virtual void ClearCaches() {} protected: - GraphicsSystem(); + GraphicsSystem(Emulator* emulator); + Emulator* emulator_; Memory* memory_; cpu::Processor* processor_; ui::PlatformLoop* target_loop_; diff --git a/src/xenia/kernel/kernel_state.cc b/src/xenia/kernel/kernel_state.cc index 4d64d7f2e..c6033ba7d 100644 --- a/src/xenia/kernel/kernel_state.cc +++ b/src/xenia/kernel/kernel_state.cc @@ -70,6 +70,15 @@ KernelState::KernelState(Emulator* emulator) KernelState::~KernelState() { SetExecutableModule(nullptr); + for (auto user_module : user_modules_) { + user_module->Release(); + } + user_modules_.clear(); + for (auto kernel_module : kernel_modules_) { + kernel_module->Release(); + } + kernel_modules_.clear(); + // Delete all objects. delete object_table_; @@ -80,10 +89,6 @@ KernelState::~KernelState() { assert_true(shared_kernel_state_ == this); shared_kernel_state_ = nullptr; - - for (XUserModule* mod : user_modules_) { - mod->Release(); - } } KernelState* KernelState::shared() { return shared_kernel_state_; } @@ -99,14 +104,15 @@ void KernelState::UnregisterModule(XModule* module) {} bool KernelState::IsKernelModule(const char* name) { if (!name) { - // executing module isn't a kernel module + // Executing module isn't a kernel module. return false; - } else if (strcasecmp(name, "xam.xex") == 0) { - return true; - } else if (strcasecmp(name, "xboxkrnl.exe") == 0) { - return true; } - + std::lock_guard lock(object_mutex_); + for (auto kernel_module : kernel_modules_) { + if (kernel_module->Matches(name)) { + return true; + } + } return false; } @@ -115,32 +121,24 @@ XModule* KernelState::GetModule(const char* name) { // NULL name = self. // TODO(benvanik): lookup module from caller address. return GetExecutableModule(); - } else if (strcasecmp(name, "xam.xex") == 0) { - auto module = emulator_->xam(); - module->Retain(); - return module; - } else if (strcasecmp(name, "xboxkrnl.exe") == 0) { - auto module = emulator_->xboxkrnl(); - module->Retain(); - return module; } else if (strcasecmp(name, "kernel32.dll") == 0) { // Some games request this, for some reason. wtf. - return nullptr; - } else { - std::lock_guard lock(object_mutex_); - - for (XUserModule* module : user_modules_) { - if ((strcasecmp(xe::find_name_from_path(module->path()).c_str(), name) == - 0) || - (strcasecmp(module->name().c_str(), name) == 0) || - (strcasecmp(module->path().c_str(), name) == 0)) { - module->Retain(); - return module; - } - } - return nullptr; } + std::lock_guard lock(object_mutex_); + for (auto kernel_module : kernel_modules_) { + if (kernel_module->Matches(name)) { + kernel_module->Retain(); + return kernel_module; + } + } + for (auto user_module : user_modules_) { + if (user_module->Matches(name)) { + user_module->Retain(); + return user_module; + } + } + return nullptr; } XUserModule* KernelState::GetExecutableModule() { @@ -166,6 +164,11 @@ void KernelState::SetExecutableModule(XUserModule* module) { } } +void KernelState::LoadKernelModule(XKernelModule* kernel_module) { + std::lock_guard lock(object_mutex_); + kernel_modules_.push_back(kernel_module); +} + XUserModule* KernelState::LoadUserModule(const char* raw_name) { // Some games try to load relative to launch module, others specify full path. std::string name = xe::find_name_from_path(raw_name); diff --git a/src/xenia/kernel/kernel_state.h b/src/xenia/kernel/kernel_state.h index f70f123e6..eab953d2c 100644 --- a/src/xenia/kernel/kernel_state.h +++ b/src/xenia/kernel/kernel_state.h @@ -37,6 +37,7 @@ namespace xe { namespace kernel { class Dispatcher; +class XKernelModule; class XModule; class XNotifyListener; class XThread; @@ -74,7 +75,13 @@ class KernelState { XModule* GetModule(const char* name); XUserModule* GetExecutableModule(); void SetExecutableModule(XUserModule* module); - XUserModule* LoadUserModule(const char *name); + template + XKernelModule* LoadKernelModule() { + auto kernel_module = std::make_unique(emulator_, this); + LoadKernelModule(kernel_module.get()); + return kernel_module.release(); + } + XUserModule* LoadUserModule(const char* name); void RegisterThread(XThread* thread); void UnregisterThread(XThread* thread); @@ -94,6 +101,8 @@ class KernelState { uint32_t extended_error, uint32_t length); private: + void LoadKernelModule(XKernelModule* kernel_module); + Emulator* emulator_; Memory* memory_; cpu::Processor* processor_; @@ -113,7 +122,7 @@ class KernelState { uint32_t process_type_; XUserModule* executable_module_; - + std::vector kernel_modules_; std::vector user_modules_; friend class XObject; diff --git a/src/xenia/kernel/objects/xmodule.cc b/src/xenia/kernel/objects/xmodule.cc index 192ae6525..fc1e4247d 100644 --- a/src/xenia/kernel/objects/xmodule.cc +++ b/src/xenia/kernel/objects/xmodule.cc @@ -9,6 +9,8 @@ #include "xenia/kernel/objects/xmodule.h" +#include "xenia/base/string.h" + namespace xe { namespace kernel { @@ -31,6 +33,19 @@ XModule::XModule(KernelState* kernel_state, const std::string& path) XModule::~XModule() { kernel_state_->UnregisterModule(this); } +bool XModule::Matches(const std::string& name) const { + if (strcasecmp(xe::find_name_from_path(path_).c_str(), name.c_str()) == 0) { + return true; + } + if (strcasecmp(name_.c_str(), name.c_str()) == 0) { + return true; + } + if (strcasecmp(path_.c_str(), name.c_str()) == 0) { + return true; + } + return false; +} + void XModule::OnLoad() { kernel_state_->RegisterModule(this); } X_STATUS XModule::GetSection(const char* name, uint32_t* out_section_data, diff --git a/src/xenia/kernel/objects/xmodule.h b/src/xenia/kernel/objects/xmodule.h index 51218e8ac..123ace447 100644 --- a/src/xenia/kernel/objects/xmodule.h +++ b/src/xenia/kernel/objects/xmodule.h @@ -25,6 +25,7 @@ class XModule : public XObject { const std::string& path() const { return path_; } const std::string& name() const { return name_; } + bool Matches(const std::string& name) const; virtual uint32_t GetProcAddressByOrdinal(uint16_t ordinal) = 0; virtual uint32_t GetProcAddressByName(const char* name) = 0; diff --git a/src/xenia/kernel/objects/xthread.cc b/src/xenia/kernel/objects/xthread.cc index 623787f04..11d6d74e9 100644 --- a/src/xenia/kernel/objects/xthread.cc +++ b/src/xenia/kernel/objects/xthread.cc @@ -156,7 +156,7 @@ X_STATUS XThread::Create() { scratch_address_ = memory()->SystemHeapAlloc(scratch_size_); // Allocate TLS block. - uint32_t tls_size = 32; // Default 32 (is this OK?) + uint32_t tls_size = 32; // Default 32 (is this OK?) if (module && module->xex_header()) { const xe_xex2_header_t* header = module->xex_header(); tls_size = header->tls_info.slot_count * header->tls_info.data_size; @@ -194,15 +194,15 @@ X_STATUS XThread::Create() { thread_state_->stack_base()); uint8_t* pcr = memory()->TranslateVirtual(pcr_address_); - std::memset(pcr, 0x0, 0x2D8 + 0xAB0); // Zero the PCR + std::memset(pcr, 0x0, 0x2D8 + 0xAB0); // Zero the PCR xe::store_and_swap(pcr + 0x000, tls_address_); xe::store_and_swap(pcr + 0x030, pcr_address_); xe::store_and_swap(pcr + 0x070, thread_state_->stack_address() + thread_state_->stack_size()); xe::store_and_swap(pcr + 0x074, thread_state_->stack_address()); xe::store_and_swap(pcr + 0x100, thread_state_address_); - xe::store_and_swap (pcr + 0x10C, 1); // Current CPU(?) - xe::store_and_swap(pcr + 0x150, 0); // DPC active bool? + xe::store_and_swap(pcr + 0x10C, 1); // Current CPU(?) + xe::store_and_swap(pcr + 0x150, 0); // DPC active bool? // Setup the thread state block (last error/etc). uint8_t* p = memory()->TranslateVirtual(thread_state_address_); @@ -622,15 +622,14 @@ X_STATUS XThread::Delay(uint32_t processor_mode, uint32_t alertable, void* XThread::GetWaitHandle() { return event_->GetWaitHandle(); } XHostThread::XHostThread(KernelState* kernel_state, uint32_t stack_size, - uint32_t creation_flags, std::function host_fn): - XThread(kernel_state, stack_size, 0, 0, 0, creation_flags), - host_fn_(host_fn) { -} + uint32_t creation_flags, std::function host_fn) + : XThread(kernel_state, stack_size, 0, 0, 0, creation_flags), + host_fn_(host_fn) {} void XHostThread::Execute() { - XELOGKERNEL("XThread::Execute thid %d (handle=%.8X, '%s', native=%.8X, )", - thread_id_, handle(), name_.c_str(), - xe::threading::current_thread_id()); + XELOGKERNEL( + "XThread::Execute thid %d (handle=%.8X, '%s', native=%.8X, )", + thread_id_, handle(), name_.c_str(), xe::threading::current_thread_id()); // Let the kernel know we are starting. kernel_state()->OnThreadExecute(this); diff --git a/src/xenia/kernel/objects/xuser_module.cc b/src/xenia/kernel/objects/xuser_module.cc index 230627477..c05cd9435 100644 --- a/src/xenia/kernel/objects/xuser_module.cc +++ b/src/xenia/kernel/objects/xuser_module.cc @@ -354,7 +354,7 @@ void XUserModule::Dump() { if (kernel_state_->IsKernelModule(library->name)) { KernelExport* kernel_export = - export_resolver->GetExportByOrdinal(library->name, info->ordinal); + export_resolver->GetExportByOrdinal(library->name, info->ordinal); if (kernel_export) { known_count++; if (kernel_export->is_implemented) { @@ -371,7 +371,7 @@ void XUserModule::Dump() { XModule* module = kernel_state_->GetModule(library->name); if (module) { uint32_t export_addr = - module->GetProcAddressByOrdinal(info->ordinal); + module->GetProcAddressByOrdinal(info->ordinal); if (export_addr) { impl_count++; known_count++; @@ -400,10 +400,10 @@ void XUserModule::Dump() { const char* name = "UNKNOWN"; bool implemented = false; - KernelExport* kernel_export; + KernelExport* kernel_export = nullptr; if (kernel_state_->IsKernelModule(library->name)) { kernel_export = - export_resolver->GetExportByOrdinal(library->name, info->ordinal); + export_resolver->GetExportByOrdinal(library->name, info->ordinal); if (kernel_export) { name = kernel_export->name; implemented = kernel_export->is_implemented; diff --git a/src/xenia/ui/win32/win32_control.cc b/src/xenia/ui/win32/win32_control.cc index 7ba359edf..e67644fc2 100644 --- a/src/xenia/ui/win32/win32_control.cc +++ b/src/xenia/ui/win32/win32_control.cc @@ -17,6 +17,7 @@ Win32Control::Win32Control(uint32_t flags) : Control(flags), hwnd_(nullptr) {} Win32Control::~Win32Control() { if (hwnd_) { + SetWindowLongPtr(hwnd_, GWLP_USERDATA, 0); CloseWindow(hwnd_); hwnd_ = nullptr; } diff --git a/src/xenia/ui/win32/win32_loop.cc b/src/xenia/ui/win32/win32_loop.cc index f85221db8..38f325500 100644 --- a/src/xenia/ui/win32/win32_loop.cc +++ b/src/xenia/ui/win32/win32_loop.cc @@ -29,7 +29,7 @@ class PostedFn { Win32Loop::Win32Loop() : thread_id_(0) { xe::threading::Fence init_fence; - thread_ = std::thread([&]() { + thread_ = std::thread([&init_fence, this]() { xe::threading::set_name("Win32 Loop"); thread_id_ = GetCurrentThreadId(); @@ -46,7 +46,10 @@ Win32Loop::Win32Loop() : thread_id_(0) { init_fence.Wait(); } -Win32Loop::~Win32Loop() = default; +Win32Loop::~Win32Loop() { + Quit(); + thread_.join(); +} void Win32Loop::ThreadMain() { MSG msg;