From 01f0b14250a57752354345427020e7d3cecf0176 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 16 Aug 2014 01:36:45 -0700 Subject: [PATCH] Removing xe_thread_t. --- src/poly/threading.h | 4 + src/poly/threading_mac.cc | 8 ++ src/poly/threading_win.cc | 30 ++++++ src/xenia/apu/audio_system.cc | 16 ++-- src/xenia/apu/audio_system.h | 9 +- src/xenia/core.h | 1 - src/xenia/core/run_loop_win.cc | 2 - src/xenia/core/sources.gypi | 2 - src/xenia/core/thread.cc | 153 ------------------------------- src/xenia/core/thread.h | 34 ------- src/xenia/gpu/graphics_system.cc | 16 ++-- src/xenia/gpu/graphics_system.h | 10 +- 12 files changed, 69 insertions(+), 216 deletions(-) delete mode 100644 src/xenia/core/thread.cc delete mode 100644 src/xenia/core/thread.h diff --git a/src/poly/threading.h b/src/poly/threading.h index 431dda291..61e74a300 100644 --- a/src/poly/threading.h +++ b/src/poly/threading.h @@ -12,6 +12,7 @@ #include #include +#include #include @@ -25,6 +26,9 @@ uint64_t ticks(); // purposes only. uint32_t current_thread_id(); +// Sets the current thread name. +void set_name(const std::string& name); + // Yields the current thread to the scheduler. Maybe. void Yield(); diff --git a/src/poly/threading_mac.cc b/src/poly/threading_mac.cc index 5ee15b677..b0ec61406 100644 --- a/src/poly/threading_mac.cc +++ b/src/poly/threading_mac.cc @@ -24,6 +24,14 @@ uint32_t current_thread_id() { return static_cast(tid); } +void set_name(const std::string& name) { +#if XE_LIKE_OSX + pthread_setname_np(name.c_str()); +#else + pthread_setname_np(pthread_self(), name.c_str()); +#endif // XE_LIKE_OSX +} + void Yield() { pthread_yield_np(); } void Sleep(std::chrono::microseconds duration) { diff --git a/src/poly/threading_win.cc b/src/poly/threading_win.cc index 27689ab28..d5a1a2b3f 100644 --- a/src/poly/threading_win.cc +++ b/src/poly/threading_win.cc @@ -27,6 +27,36 @@ uint32_t current_thread_id() { return static_cast(GetCurrentThreadId()); } +// http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx +#pragma pack(push, 8) +struct THREADNAME_INFO { + DWORD dwType; // Must be 0x1000. + LPCSTR szName; // Pointer to name (in user addr space). + DWORD dwThreadID; // Thread ID (-1=caller thread). + DWORD dwFlags; // Reserved for future use, must be zero. +}; +#pragma pack(pop) + +void set_name(DWORD thread_id, const std::string& name) { + if (!IsDebuggerPresent()) { + return; + } + THREADNAME_INFO info; + info.dwType = 0x1000; + info.szName = name.c_str(); + info.dwThreadID = thread_id; + info.dwFlags = 0; + __try { + RaiseException(0x406D1388, 0, sizeof(info) / sizeof(ULONG_PTR), + reinterpret_cast(&info)); + } + __except(EXCEPTION_EXECUTE_HANDLER) {} +} + +void set_name(const std::string& name) { + set_name(static_cast(-1), name); +} + void Yield() { SwitchToThread(); } void Sleep(std::chrono::microseconds duration) { diff --git a/src/xenia/apu/audio_system.cc b/src/xenia/apu/audio_system.cc index 4eb659120..c61e1fe84 100644 --- a/src/xenia/apu/audio_system.cc +++ b/src/xenia/apu/audio_system.cc @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -22,7 +23,7 @@ using namespace xe::cpu; AudioSystem::AudioSystem(Emulator* emulator) : emulator_(emulator), memory_(emulator->memory()), - thread_(0), running_(false) { + running_(false) { memset(clients_, 0, sizeof(clients_)); for (size_t i = 0; i < maximum_client_count_; ++i) { client_wait_handles_[i] = CreateEvent(NULL, TRUE, FALSE, NULL); @@ -61,15 +62,15 @@ X_STATUS AudioSystem::Setup() { // Init needs to happen there so that any thread-local stuff // is created on the right thread. running_ = true; - thread_ = xe_thread_create( - "AudioSystem", - (xe_thread_callback)ThreadStartThunk, this); - xe_thread_start(thread_); + thread_ = std::thread(std::bind(&AudioSystem::ThreadStart, this)); return X_STATUS_SUCCESS; } void AudioSystem::ThreadStart() { + poly::threading::set_name("AudioSystemThread"); + xe::Profiler::ThreadEnter("AudioSystemThread"); + // Initialize driver and ringbuffer. Initialize(); @@ -113,6 +114,8 @@ void AudioSystem::ThreadStart() { running_ = false; // TODO(benvanik): call module API to kill? + + xe::Profiler::ThreadExit(); } void AudioSystem::Initialize() { @@ -120,8 +123,7 @@ void AudioSystem::Initialize() { void AudioSystem::Shutdown() { running_ = false; - xe_thread_join(thread_); - xe_thread_release(thread_); + thread_.join(); delete thread_state_; memory()->HeapFree(thread_block_, 0); diff --git a/src/xenia/apu/audio_system.h b/src/xenia/apu/audio_system.h index 4eadcaa71..25f871745 100644 --- a/src/xenia/apu/audio_system.h +++ b/src/xenia/apu/audio_system.h @@ -10,8 +10,10 @@ #ifndef XENIA_APU_AUDIO_SYSTEM_H_ #define XENIA_APU_AUDIO_SYSTEM_H_ +#include #include #include +#include #include #include @@ -50,9 +52,6 @@ protected: virtual void Initialize(); private: - static void ThreadStartThunk(AudioSystem* this_ptr) { - this_ptr->ThreadStart(); - } void ThreadStart(); static uint64_t MMIOReadRegisterThunk(AudioSystem* as, uint64_t addr) { @@ -70,10 +69,10 @@ protected: Memory* memory_; cpu::Processor* processor_; - xe_thread_ref thread_; + std::thread thread_; cpu::XenonThreadState* thread_state_; uint32_t thread_block_; - bool running_; + std::atomic running_; std::mutex lock_; diff --git a/src/xenia/core.h b/src/xenia/core.h index a447d6167..3f606cc7a 100644 --- a/src/xenia/core.h +++ b/src/xenia/core.h @@ -24,6 +24,5 @@ namespace xe { #include #include #include -#include #endif // XENIA_CORE_H_ diff --git a/src/xenia/core/run_loop_win.cc b/src/xenia/core/run_loop_win.cc index 0365bfd93..164932f1b 100644 --- a/src/xenia/core/run_loop_win.cc +++ b/src/xenia/core/run_loop_win.cc @@ -9,8 +9,6 @@ #include -#include - typedef struct xe_run_loop { xe_ref_t ref; diff --git a/src/xenia/core/sources.gypi b/src/xenia/core/sources.gypi index ae943948b..450a12cbd 100644 --- a/src/xenia/core/sources.gypi +++ b/src/xenia/core/sources.gypi @@ -11,8 +11,6 @@ 'ref.h', 'run_loop.h', 'socket.h', - 'thread.cc', - 'thread.h', ], 'conditions': [ diff --git a/src/xenia/core/thread.cc b/src/xenia/core/thread.cc deleted file mode 100644 index 8aace9ee4..000000000 --- a/src/xenia/core/thread.cc +++ /dev/null @@ -1,153 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include - - -typedef struct xe_thread { - xe_ref_t ref; - - char* name; - - xe_thread_callback callback; - void* callback_param; - - void* handle; -} xe_thread_t; - - - -xe_thread_ref xe_thread_create( - const char* name, xe_thread_callback callback, void* param) { - xe_thread_ref thread = (xe_thread_ref)xe_calloc(sizeof(xe_thread_t)); - xe_ref_init((xe_ref)thread); - - thread->name = xestrdupa(name); - thread->callback = callback; - thread->callback_param = param; - - return thread; -} - -void xe_thread_dealloc(xe_thread_ref thread) { - thread->handle = NULL; - xe_free(thread->name); -} - -xe_thread_ref xe_thread_retain(xe_thread_ref thread) { - xe_ref_retain((xe_ref)thread); - return thread; -} - -void xe_thread_release(xe_thread_ref thread) { - xe_ref_release((xe_ref)thread, (xe_ref_dealloc_t)xe_thread_dealloc); -} - -#if XE_PLATFORM_WIN32 - -// http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx -#pragma pack(push,8) -typedef struct tagTHREADNAME_INFO -{ - DWORD dwType; // Must be 0x1000. - LPCSTR szName; // Pointer to name (in user addr space). - DWORD dwThreadID; // Thread ID (-1=caller thread). - DWORD dwFlags; // Reserved for future use, must be zero. -} THREADNAME_INFO; -#pragma pack(pop) - -#pragma warning(disable : 6320; disable : 6322) -static uint32_t __stdcall xe_thread_callback_win32(void* param) { - xe_thread_t* thread = reinterpret_cast(param); - - if (IsDebuggerPresent()) { - THREADNAME_INFO info; - info.dwType = 0x1000; - info.szName = thread->name; - info.dwThreadID = (DWORD)-1; - info.dwFlags = 0; - __try { - RaiseException(0x406D1388, 0, sizeof(info) / sizeof(ULONG_PTR), - (ULONG_PTR*)&info); - } __except(EXCEPTION_EXECUTE_HANDLER) { - } - } - - xe::Profiler::ThreadEnter(thread->name); - thread->callback(thread->callback_param); - xe::Profiler::ThreadExit(); - return 0; -} -#pragma warning(default : 6320; default : 6322) - -int xe_thread_start(xe_thread_ref thread) { - HANDLE thread_handle = CreateThread( - NULL, - 0, - (LPTHREAD_START_ROUTINE)xe_thread_callback_win32, - thread, - 0, - NULL); - if (!thread_handle) { - uint32_t last_error = GetLastError(); - // TODO(benvanik): translate? - XELOGE("CreateThread failed with %d", last_error); - return last_error; - } - - thread->handle = reinterpret_cast(thread_handle); - - return 0; -} - -void xe_thread_join(xe_thread_ref thread) { - HANDLE thread_handle = (HANDLE)thread->handle; - WaitForSingleObject(thread_handle, INFINITE); -} - -#else - -static void* xe_thread_callback_pthreads(void* param) { - xe_thread_t* thread = reinterpret_cast(param); -#if XE_LIKE_OSX - XEIGNORE(pthread_setname_np(thread->name)); -#else - pthread_setname_np(pthread_self(), thread->name); -#endif // OSX - xe::Profiler::ThreadEnter(thread->name); - thread->callback(thread->callback_param); - xe::Profiler::ThreadExit(); - return 0; -} - -int xe_thread_start(xe_thread_ref thread) { - pthread_attr_t attr; - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - pthread_t thread_handle; - int result_code = pthread_create( - &thread_handle, - &attr, - &xe_thread_callback_pthreads, - thread); - pthread_attr_destroy(&attr); - if (result_code) { - return result_code; - } - - thread->handle = reinterpret_cast(thread_handle); - - return 0; -} - -void xe_thread_join(xe_thread_ref thread) { - pthread_join((pthread_t)thread->handle, NULL); -} - -#endif // WIN32 diff --git a/src/xenia/core/thread.h b/src/xenia/core/thread.h deleted file mode 100644 index 1aa8fb0bb..000000000 --- a/src/xenia/core/thread.h +++ /dev/null @@ -1,34 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_CORE_THREAD_H_ -#define XENIA_CORE_THREAD_H_ - -#include -#include -#include - - -struct xe_thread; -typedef struct xe_thread* xe_thread_ref; - - -typedef void (*xe_thread_callback)(void* param); - - -xe_thread_ref xe_thread_create( - const char* name, xe_thread_callback callback, void* param); -xe_thread_ref xe_thread_retain(xe_thread_ref thread); -void xe_thread_release(xe_thread_ref thread); - -int xe_thread_start(xe_thread_ref thread); -void xe_thread_join(xe_thread_ref thread); - - -#endif // XENIA_CORE_THREAD_H_ diff --git a/src/xenia/gpu/graphics_system.cc b/src/xenia/gpu/graphics_system.cc index abd03e2d6..6ab0d14ff 100644 --- a/src/xenia/gpu/graphics_system.cc +++ b/src/xenia/gpu/graphics_system.cc @@ -9,6 +9,7 @@ #include +#include #include #include #include @@ -25,7 +26,7 @@ using namespace xe::gpu::xenos; GraphicsSystem::GraphicsSystem(Emulator* emulator) : emulator_(emulator), memory_(emulator->memory()), - thread_(nullptr), running_(false), driver_(nullptr), + running_(false), driver_(nullptr), command_processor_(nullptr), interrupt_callback_(0), interrupt_callback_data_(0), last_interrupt_time_(0), thread_wait_(nullptr) { @@ -59,15 +60,15 @@ X_STATUS GraphicsSystem::Setup() { // Init needs to happen there so that any thread-local stuff // is created on the right thread. running_ = true; - thread_ = xe_thread_create( - "GraphicsSystem", - (xe_thread_callback)ThreadStartThunk, this); - xe_thread_start(thread_); + thread_ = std::thread(std::bind(&GraphicsSystem::ThreadStart, this)); WaitForSingleObject(thread_wait_, INFINITE); return X_STATUS_SUCCESS; } void GraphicsSystem::ThreadStart() { + poly::threading::set_name("GraphicsSystemThread"); + xe::Profiler::ThreadEnter("GraphicsSystemThread"); + xe_run_loop_ref run_loop = xe_run_loop_retain(run_loop_); // Initialize driver and ringbuffer. @@ -101,6 +102,8 @@ void GraphicsSystem::ThreadStart() { running_ = false; xe_run_loop_release(run_loop); + + xe::Profiler::ThreadExit(); } void GraphicsSystem::Initialize() { @@ -108,8 +111,7 @@ void GraphicsSystem::Initialize() { void GraphicsSystem::Shutdown() { running_ = false; - xe_thread_join(thread_); - xe_thread_release(thread_); + thread_.join(); delete command_processor_; diff --git a/src/xenia/gpu/graphics_system.h b/src/xenia/gpu/graphics_system.h index 3b8fdabb1..84685db79 100644 --- a/src/xenia/gpu/graphics_system.h +++ b/src/xenia/gpu/graphics_system.h @@ -10,6 +10,9 @@ #ifndef XENIA_GPU_GRAPHICS_SYSTEM_H_ #define XENIA_GPU_GRAPHICS_SYSTEM_H_ +#include +#include + #include #include @@ -52,9 +55,6 @@ protected: virtual void Pump() = 0; private: - static void ThreadStartThunk(GraphicsSystem* this_ptr) { - this_ptr->ThreadStart(); - } void ThreadStart(); static uint64_t MMIOReadRegisterThunk(GraphicsSystem* gs, uint64_t addr) { @@ -73,8 +73,8 @@ protected: cpu::Processor* processor_; xe_run_loop_ref run_loop_; - xe_thread_ref thread_; - bool running_; + std::thread thread_; + std::atomic running_; GraphicsDriver* driver_; CommandProcessor* command_processor_;