From 3150f41ea0591f47256a3849a7631c358b5fb1a4 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Tue, 5 Aug 2014 09:10:00 -0700 Subject: [PATCH] oh ffs - properly suspending threads on creation. --- src/xenia/kernel/objects/xthread.cc | 20 ++++++++++++++++++-- src/xenia/kernel/objects/xthread.h | 1 + src/xenia/kernel/xboxkrnl_threading.cc | 3 +-- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/xenia/kernel/objects/xthread.cc b/src/xenia/kernel/objects/xthread.cc index 0e3dab0c5..f10306baf 100644 --- a/src/xenia/kernel/objects/xthread.cc +++ b/src/xenia/kernel/objects/xthread.cc @@ -9,6 +9,8 @@ #include +#include + #include #include #include @@ -47,6 +49,9 @@ XThread::XThread(KernelState* kernel_state, creation_params_.xapi_thread_startup = xapi_thread_startup; creation_params_.start_address = start_address; creation_params_.start_context = start_context; + + // top 8 bits = processor ID (or 0 for default) + // bit 0 = 1 to create suspended creation_params_.creation_flags = creation_flags; // Adjust stack size - min of 16k. @@ -244,6 +249,11 @@ X_STATUS XThread::Create() { xesnprintfa(thread_name, XECOUNT(thread_name), "XThread%04X", handle()); set_name(thread_name); + uint32_t proc_mask = creation_params_.creation_flags >> 24; + if (proc_mask) { + SetAffinity(proc_mask); + } + module->Release(); return X_STATUS_SUCCESS; } @@ -277,12 +287,13 @@ static uint32_t __stdcall XThreadStartCallbackWin32(void* param) { } X_STATUS XThread::PlatformCreate() { + bool suspended = creation_params_.creation_flags & 0x1; thread_handle_ = CreateThread( NULL, creation_params_.stack_size, (LPTHREAD_START_ROUTINE)XThreadStartCallbackWin32, this, - creation_params_.creation_flags, + suspended ? CREATE_SUSPENDED : 0, NULL); if (!thread_handle_) { uint32_t last_error = GetLastError(); @@ -325,7 +336,7 @@ X_STATUS XThread::PlatformCreate() { pthread_attr_setstacksize(&attr, creation_params_.stack_size); int result_code; - if (creation_params_.creation_flags & X_CREATE_SUSPENDED) { + if (creation_params_.creation_flags & 0x1) { #if XE_PLATFORM_OSX result_code = pthread_create_suspended_np( reinterpret_cast(&thread_handle_), @@ -521,6 +532,11 @@ void XThread::SetPriority(int32_t increment) { SetThreadPriority(thread_handle_, increment); } +void XThread::SetAffinity(uint32_t affinity) { + // TODO(benvanik): implement. + XELOGW("KeSetAffinityThread not implemented"); +} + X_STATUS XThread::Resume(uint32_t* out_suspend_count) { DWORD result = ResumeThread(thread_handle_); if (result >= 0) { diff --git a/src/xenia/kernel/objects/xthread.h b/src/xenia/kernel/objects/xthread.h index cec3c4dce..3b1f236aa 100644 --- a/src/xenia/kernel/objects/xthread.h +++ b/src/xenia/kernel/objects/xthread.h @@ -62,6 +62,7 @@ public: int32_t QueryPriority(); void SetPriority(int32_t increment); + void SetAffinity(uint32_t affinity); X_STATUS Resume(uint32_t* out_suspend_count); X_STATUS Suspend(uint32_t* out_suspend_count); diff --git a/src/xenia/kernel/xboxkrnl_threading.cc b/src/xenia/kernel/xboxkrnl_threading.cc index 0078dbfc7..4b6e72258 100644 --- a/src/xenia/kernel/xboxkrnl_threading.cc +++ b/src/xenia/kernel/xboxkrnl_threading.cc @@ -281,8 +281,7 @@ uint32_t xeKeSetAffinityThread(void* thread_ptr, uint32_t affinity) { XThread* thread = (XThread*)XObject::GetObject(state, thread_ptr); if (thread) { - // TODO(benvanik): implement. - XELOGW("KeSetAffinityThread not implemented"); + thread->SetAffinity(affinity); } return affinity;