Suspend/resume working.
This commit is contained in:
@@ -218,6 +218,10 @@ void Processor::OnDebugClientDisconnected(uint32_t client_id) {
|
||||
debug_client_states_.erase(client_id);
|
||||
xe_mutex_unlock(debug_client_states_lock_);
|
||||
delete client_state;
|
||||
|
||||
// Whenever we support multiple clients we will need to respect pause
|
||||
// settings. For now, resume until running.
|
||||
runtime_->debugger()->ResumeAllThreads(true);
|
||||
}
|
||||
|
||||
json_t* Processor::OnDebugRequest(
|
||||
@@ -417,6 +421,21 @@ json_t* Processor::OnDebugRequest(
|
||||
return json_string("Unable to remove breakpoints");
|
||||
}
|
||||
return json_null();
|
||||
} else if (xestrcmpa(command, "continue") == 0) {
|
||||
if (runtime_->debugger()->ResumeAllThreads()) {
|
||||
succeeded = false;
|
||||
return json_string("Unable to resume threads");
|
||||
}
|
||||
return json_null();
|
||||
} else if (xestrcmpa(command, "break") == 0) {
|
||||
if (runtime_->debugger()->SuspendAllThreads()) {
|
||||
succeeded = false;
|
||||
return json_string("Unable to suspend threads");
|
||||
}
|
||||
return json_null();
|
||||
} else if (xestrcmpa(command, "step") == 0) {
|
||||
// threadId
|
||||
return json_null();
|
||||
} else {
|
||||
succeeded = false;
|
||||
return json_string("Unknown command");
|
||||
|
||||
@@ -28,6 +28,8 @@ XenonThreadState::XenonThreadState(
|
||||
stack_address_ = memory_->HeapAlloc(
|
||||
0, stack_size, MEMORY_FLAG_ZERO);
|
||||
|
||||
debug_break_ = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
|
||||
// Allocate with 64b alignment.
|
||||
context_ = (PPCContext*)xe_malloc_aligned(sizeof(PPCContext));
|
||||
XEASSERT(((uint64_t)context_ & 0xF) == 0);
|
||||
@@ -53,6 +55,8 @@ XenonThreadState::XenonThreadState(
|
||||
XenonThreadState::~XenonThreadState() {
|
||||
runtime_->debugger()->OnThreadDestroyed(this);
|
||||
|
||||
CloseHandle(debug_break_);
|
||||
|
||||
alloy::tracing::WriteEvent(EventType::ThreadDeinit({
|
||||
}));
|
||||
|
||||
@@ -60,10 +64,31 @@ XenonThreadState::~XenonThreadState() {
|
||||
memory_->HeapFree(stack_address_, stack_size_);
|
||||
}
|
||||
|
||||
volatile int* XenonThreadState::suspend_flag_address() const {
|
||||
return &context_->suspend_flag;
|
||||
}
|
||||
|
||||
int XenonThreadState::Suspend(uint32_t timeout_ms) {
|
||||
// Set suspend flag.
|
||||
// One of the checks should call in to OnSuspend() at some point.
|
||||
xe_atomic_inc_32(&context_->suspend_flag);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int XenonThreadState::Resume() {
|
||||
int XenonThreadState::Resume(bool force) {
|
||||
if (context_->suspend_flag) {
|
||||
if (force) {
|
||||
context_->suspend_flag = 0;
|
||||
SetEvent(debug_break_);
|
||||
} else {
|
||||
if (!xe_atomic_dec_32(&context_->suspend_flag)) {
|
||||
SetEvent(debug_break_);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void XenonThreadState::EnterSuspend() {
|
||||
WaitForSingleObject(debug_break_, INFINITE);
|
||||
}
|
||||
|
||||
@@ -31,8 +31,10 @@ public:
|
||||
|
||||
PPCContext* context() const { return context_; }
|
||||
|
||||
virtual volatile int* suspend_flag_address() const;
|
||||
virtual int Suspend(uint32_t timeout_ms = UINT_MAX);
|
||||
virtual int Resume();
|
||||
virtual int Resume(bool force = false);
|
||||
virtual void EnterSuspend();
|
||||
|
||||
private:
|
||||
size_t stack_size_;
|
||||
@@ -44,6 +46,8 @@ private:
|
||||
|
||||
// NOTE: must be 64b aligned for SSE ops.
|
||||
PPCContext* context_;
|
||||
|
||||
HANDLE debug_break_;
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user