XThread: Special case save/restore for threads no longer running.
This commit is contained in:
parent
b58e9afbf1
commit
07d31862f1
|
@ -775,7 +775,12 @@ bool XThread::StepToAddress(uint32_t pc) {
|
||||||
fence.Signal();
|
fence.Signal();
|
||||||
});
|
});
|
||||||
if (bp.Install()) {
|
if (bp.Install()) {
|
||||||
thread_->Resume();
|
// HACK
|
||||||
|
uint32_t suspend_count = 1;
|
||||||
|
while (suspend_count) {
|
||||||
|
thread_->Resume(&suspend_count);
|
||||||
|
}
|
||||||
|
|
||||||
fence.Wait();
|
fence.Wait();
|
||||||
bp.Uninstall();
|
bp.Uninstall();
|
||||||
} else {
|
} else {
|
||||||
|
@ -859,7 +864,12 @@ uint32_t XThread::StepIntoBranch(uint32_t pc) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
thread_->Resume();
|
// HACK
|
||||||
|
uint32_t suspend_count = 1;
|
||||||
|
while (suspend_count) {
|
||||||
|
thread_->Resume(&suspend_count);
|
||||||
|
}
|
||||||
|
|
||||||
fence.Wait();
|
fence.Wait();
|
||||||
bpt.Uninstall();
|
bpt.Uninstall();
|
||||||
bpf.Uninstall();
|
bpf.Uninstall();
|
||||||
|
@ -1005,9 +1015,10 @@ uint32_t XThread::StepToSafePoint(bool ignore_host) {
|
||||||
|
|
||||||
struct ThreadSavedState {
|
struct ThreadSavedState {
|
||||||
uint32_t thread_id;
|
uint32_t thread_id;
|
||||||
bool main_thread;
|
bool is_main_thread; // Is this the main thread?
|
||||||
|
bool is_running;
|
||||||
|
|
||||||
// Clock settings
|
// Clock settings (invalid if not running)
|
||||||
uint64_t tick_count_;
|
uint64_t tick_count_;
|
||||||
uint64_t system_time_;
|
uint64_t system_time_;
|
||||||
|
|
||||||
|
@ -1018,6 +1029,8 @@ struct ThreadSavedState {
|
||||||
uint32_t stack_limit; // Low address
|
uint32_t stack_limit; // Low address
|
||||||
uint32_t stack_alloc_base; // Allocation address
|
uint32_t stack_alloc_base; // Allocation address
|
||||||
uint32_t stack_alloc_size; // Allocation size
|
uint32_t stack_alloc_size; // Allocation size
|
||||||
|
|
||||||
|
// Context (invalid if not running)
|
||||||
struct {
|
struct {
|
||||||
uint64_t lr;
|
uint64_t lr;
|
||||||
uint64_t ctr;
|
uint64_t ctr;
|
||||||
|
@ -1042,13 +1055,16 @@ bool XThread::Save(ByteStream* stream) {
|
||||||
|
|
||||||
XELOGD("XThread %.8X serializing...", handle());
|
XELOGD("XThread %.8X serializing...", handle());
|
||||||
|
|
||||||
uint32_t pc = StepToSafePoint();
|
uint32_t pc = 0;
|
||||||
|
if (running_) {
|
||||||
|
pc = StepToSafePoint();
|
||||||
if (!pc) {
|
if (!pc) {
|
||||||
XELOGE("XThread %.8X failed to save: could not step to a safe point!",
|
XELOGE("XThread %.8X failed to save: could not step to a safe point!",
|
||||||
handle());
|
handle());
|
||||||
assert_always();
|
assert_always();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!SaveObject(stream)) {
|
if (!SaveObject(stream)) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -1059,7 +1075,8 @@ bool XThread::Save(ByteStream* stream) {
|
||||||
|
|
||||||
ThreadSavedState state;
|
ThreadSavedState state;
|
||||||
state.thread_id = thread_id_;
|
state.thread_id = thread_id_;
|
||||||
state.main_thread = main_thread_;
|
state.is_main_thread = main_thread_;
|
||||||
|
state.is_running = running_;
|
||||||
state.apc_head = apc_list_.head();
|
state.apc_head = apc_list_.head();
|
||||||
state.tls_address = tls_address_;
|
state.tls_address = tls_address_;
|
||||||
state.pcr_address = pcr_address_;
|
state.pcr_address = pcr_address_;
|
||||||
|
@ -1068,6 +1085,7 @@ bool XThread::Save(ByteStream* stream) {
|
||||||
state.stack_alloc_base = stack_alloc_base_;
|
state.stack_alloc_base = stack_alloc_base_;
|
||||||
state.stack_alloc_size = stack_alloc_size_;
|
state.stack_alloc_size = stack_alloc_size_;
|
||||||
|
|
||||||
|
if (running_) {
|
||||||
state.tick_count_ = Clock::QueryGuestTickCount();
|
state.tick_count_ = Clock::QueryGuestTickCount();
|
||||||
state.system_time_ =
|
state.system_time_ =
|
||||||
Clock::QueryGuestSystemTime() - Clock::guest_system_time_base();
|
Clock::QueryGuestSystemTime() - Clock::guest_system_time_base();
|
||||||
|
@ -1093,6 +1111,7 @@ bool XThread::Save(ByteStream* stream) {
|
||||||
state.context.xer_so = context->xer_so;
|
state.context.xer_so = context->xer_so;
|
||||||
state.context.vscr_sat = context->vscr_sat;
|
state.context.vscr_sat = context->vscr_sat;
|
||||||
state.context.pc = pc;
|
state.context.pc = pc;
|
||||||
|
}
|
||||||
|
|
||||||
stream->Write(&state, sizeof(ThreadSavedState));
|
stream->Write(&state, sizeof(ThreadSavedState));
|
||||||
return true;
|
return true;
|
||||||
|
@ -1121,7 +1140,7 @@ object_ref<XThread> XThread::Restore(KernelState* kernel_state,
|
||||||
ThreadSavedState state;
|
ThreadSavedState state;
|
||||||
stream->Read(&state, sizeof(ThreadSavedState));
|
stream->Read(&state, sizeof(ThreadSavedState));
|
||||||
thread->thread_id_ = state.thread_id;
|
thread->thread_id_ = state.thread_id;
|
||||||
thread->main_thread_ = state.main_thread;
|
thread->main_thread_ = state.is_main_thread;
|
||||||
thread->apc_list_.set_head(state.apc_head);
|
thread->apc_list_.set_head(state.apc_head);
|
||||||
thread->tls_address_ = state.tls_address;
|
thread->tls_address_ = state.tls_address;
|
||||||
thread->pcr_address_ = state.pcr_address;
|
thread->pcr_address_ = state.pcr_address;
|
||||||
|
@ -1138,6 +1157,8 @@ object_ref<XThread> XThread::Restore(KernelState* kernel_state,
|
||||||
thread->thread_state_ =
|
thread->thread_state_ =
|
||||||
new cpu::ThreadState(kernel_state->processor(), thread->thread_id_,
|
new cpu::ThreadState(kernel_state->processor(), thread->thread_id_,
|
||||||
thread->stack_base_, thread->pcr_address_);
|
thread->stack_base_, thread->pcr_address_);
|
||||||
|
|
||||||
|
if (state.is_running) {
|
||||||
auto context = thread->thread_state_->context();
|
auto context = thread->thread_state_->context();
|
||||||
context->kernel_state = kernel_state;
|
context->kernel_state = kernel_state;
|
||||||
context->lr = state.context.lr;
|
context->lr = state.context.lr;
|
||||||
|
@ -1185,7 +1206,8 @@ object_ref<XThread> XThread::Restore(KernelState* kernel_state,
|
||||||
current_thread_tls_ = thread;
|
current_thread_tls_ = thread;
|
||||||
|
|
||||||
uint32_t pc = state.context.pc;
|
uint32_t pc = state.context.pc;
|
||||||
thread->kernel_state()->processor()->ExecuteRaw(thread->thread_state_, pc);
|
thread->kernel_state()->processor()->ExecuteRaw(thread->thread_state_,
|
||||||
|
pc);
|
||||||
|
|
||||||
current_thread_tls_ = nullptr;
|
current_thread_tls_ = nullptr;
|
||||||
|
|
||||||
|
@ -1198,6 +1220,7 @@ object_ref<XThread> XThread::Restore(KernelState* kernel_state,
|
||||||
if (thread->emulator()->debugger()) {
|
if (thread->emulator()->debugger()) {
|
||||||
thread->emulator()->debugger()->OnThreadCreated(thread);
|
thread->emulator()->debugger()->OnThreadCreated(thread);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return object_ref<XThread>(thread);
|
return object_ref<XThread>(thread);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue