Debugger stuff. Lots of wasted work :/
This commit is contained in:
@@ -353,7 +353,7 @@ void KernelState::TerminateTitle(bool from_guest_thread) {
|
||||
|
||||
// Second: Kill all guest threads.
|
||||
for (auto it = threads_by_id_.begin(); it != threads_by_id_.end();) {
|
||||
if (it->second->guest_thread()) {
|
||||
if (it->second->is_guest_thread()) {
|
||||
auto thread = it->second;
|
||||
|
||||
if (from_guest_thread && XThread::IsInThread(thread)) {
|
||||
@@ -362,7 +362,7 @@ void KernelState::TerminateTitle(bool from_guest_thread) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (thread->running()) {
|
||||
if (thread->is_running()) {
|
||||
thread->Terminate(0);
|
||||
}
|
||||
|
||||
@@ -457,6 +457,10 @@ void KernelState::OnThreadExit(XThread* thread) {
|
||||
xe::countof(args));
|
||||
}
|
||||
}
|
||||
|
||||
if (emulator()->debugger()) {
|
||||
emulator()->debugger()->OnThreadExit(thread);
|
||||
}
|
||||
}
|
||||
|
||||
object_ref<XThread> KernelState::GetThreadByID(uint32_t thread_id) {
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "xenia/base/mutex.h"
|
||||
#include "xenia/base/threading.h"
|
||||
#include "xenia/cpu/processor.h"
|
||||
#include "xenia/emulator.h"
|
||||
#include "xenia/kernel/kernel_state.h"
|
||||
#include "xenia/kernel/native_list.h"
|
||||
#include "xenia/kernel/objects/xevent.h"
|
||||
@@ -70,6 +71,10 @@ XThread::~XThread() {
|
||||
// Unregister first to prevent lookups while deleting.
|
||||
kernel_state_->UnregisterThread(this);
|
||||
|
||||
if (emulator()->debugger()) {
|
||||
emulator()->debugger()->OnThreadDestroyed(this);
|
||||
}
|
||||
|
||||
delete apc_list_;
|
||||
|
||||
thread_.reset();
|
||||
@@ -329,6 +334,10 @@ X_STATUS XThread::Create() {
|
||||
thread_->set_priority(creation_params_.creation_flags & 0x20 ? 1 : 0);
|
||||
}
|
||||
|
||||
if (emulator()->debugger()) {
|
||||
emulator()->debugger()->OnThreadCreated(this);
|
||||
}
|
||||
|
||||
if ((creation_params_.creation_flags & X_CREATE_SUSPENDED) == 0) {
|
||||
// Start the thread now that we're all setup.
|
||||
thread_->Resume();
|
||||
@@ -344,17 +353,21 @@ X_STATUS XThread::Exit(int exit_code) {
|
||||
// TODO(benvanik); dispatch events? waiters? etc?
|
||||
RundownAPCs();
|
||||
|
||||
// Set exit code.
|
||||
X_KTHREAD* thread = guest_object<X_KTHREAD>();
|
||||
thread->header.signal_state = 1;
|
||||
thread->exit_status = exit_code;
|
||||
|
||||
kernel_state()->OnThreadExit(this);
|
||||
|
||||
if (emulator()->debugger()) {
|
||||
emulator()->debugger()->OnThreadExit(this);
|
||||
}
|
||||
|
||||
// NOTE: unless PlatformExit fails, expect it to never return!
|
||||
current_thread_tls = nullptr;
|
||||
xe::Profiler::ThreadExit();
|
||||
|
||||
// Set exit code
|
||||
X_KTHREAD* thread = guest_object<X_KTHREAD>();
|
||||
thread->header.signal_state = 1;
|
||||
thread->exit_status = exit_code;
|
||||
|
||||
running_ = false;
|
||||
Release();
|
||||
ReleaseHandle();
|
||||
@@ -367,11 +380,15 @@ X_STATUS XThread::Exit(int exit_code) {
|
||||
X_STATUS XThread::Terminate(int exit_code) {
|
||||
// TODO: Inform the profiler that this thread is exiting.
|
||||
|
||||
// Set exit code
|
||||
// Set exit code.
|
||||
X_KTHREAD* thread = guest_object<X_KTHREAD>();
|
||||
thread->header.signal_state = 1;
|
||||
thread->exit_status = exit_code;
|
||||
|
||||
if (emulator()->debugger()) {
|
||||
emulator()->debugger()->OnThreadExit(this);
|
||||
}
|
||||
|
||||
running_ = false;
|
||||
Release();
|
||||
ReleaseHandle();
|
||||
|
||||
@@ -103,6 +103,14 @@ static_assert_size(X_KTHREAD, 0xAB0);
|
||||
|
||||
class XThread : public XObject {
|
||||
public:
|
||||
struct CreationParams {
|
||||
uint32_t stack_size;
|
||||
uint32_t xapi_thread_startup;
|
||||
uint32_t start_address;
|
||||
uint32_t start_context;
|
||||
uint32_t creation_flags;
|
||||
};
|
||||
|
||||
XThread(KernelState* kernel_state, uint32_t stack_size,
|
||||
uint32_t xapi_thread_startup, uint32_t start_address,
|
||||
uint32_t start_context, uint32_t creation_flags, bool guest_thread);
|
||||
@@ -114,10 +122,11 @@ class XThread : public XObject {
|
||||
static uint32_t GetCurrentThreadHandle();
|
||||
static uint32_t GetCurrentThreadId();
|
||||
|
||||
const CreationParams* creation_params() const { return &creation_params_; }
|
||||
uint32_t tls_ptr() const { return tls_address_; }
|
||||
uint32_t pcr_ptr() const { return pcr_address_; }
|
||||
bool guest_thread() const { return guest_thread_; }
|
||||
bool running() const { return running_; }
|
||||
bool is_guest_thread() const { return guest_thread_; }
|
||||
bool is_running() const { return running_; }
|
||||
|
||||
cpu::ThreadState* thread_state() const { return thread_state_; }
|
||||
uint32_t thread_id() const { return thread_id_; }
|
||||
@@ -163,13 +172,7 @@ class XThread : public XObject {
|
||||
void DeliverAPCs();
|
||||
void RundownAPCs();
|
||||
|
||||
struct {
|
||||
uint32_t stack_size;
|
||||
uint32_t xapi_thread_startup;
|
||||
uint32_t start_address;
|
||||
uint32_t start_context;
|
||||
uint32_t creation_flags;
|
||||
} creation_params_ = {0};
|
||||
CreationParams creation_params_ = {0};
|
||||
|
||||
uint32_t thread_id_ = 0;
|
||||
std::unique_ptr<xe::threading::Thread> thread_;
|
||||
|
||||
Reference in New Issue
Block a user