Partial thread data plumbing.
This commit is contained in:
parent
aae45515ae
commit
b750370759
|
@ -312,6 +312,7 @@ namespace Xenia.Debug {
|
|||
private async Task CompleteRunStateTransition(RunState newRunState) {
|
||||
await Task.WhenAll(new Task[] {
|
||||
ModuleList.Invalidate(),
|
||||
ThreadList.Invalidate(),
|
||||
});
|
||||
|
||||
CurrentContext.SetRunState(newRunState);
|
||||
|
|
|
@ -10,8 +10,21 @@ public sealed class ListThreadsResponse : Table {
|
|||
public static ListThreadsResponse GetRootAsListThreadsResponse(ByteBuffer _bb, ListThreadsResponse obj) { return (obj.__init(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
|
||||
public ListThreadsResponse __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
|
||||
|
||||
public Thread GetThread(int j) { return GetThread(new Thread(), j); }
|
||||
public Thread GetThread(Thread obj, int j) { int o = __offset(4); return o != 0 ? obj.__init(__indirect(__vector(o) + j * 4), bb) : null; }
|
||||
public int ThreadLength { get { int o = __offset(4); return o != 0 ? __vector_len(o) : 0; } }
|
||||
|
||||
public static void StartListThreadsResponse(FlatBufferBuilder builder) { builder.StartObject(0); }
|
||||
public static int CreateListThreadsResponse(FlatBufferBuilder builder,
|
||||
int thread = 0) {
|
||||
builder.StartObject(1);
|
||||
ListThreadsResponse.AddThread(builder, thread);
|
||||
return ListThreadsResponse.EndListThreadsResponse(builder);
|
||||
}
|
||||
|
||||
public static void StartListThreadsResponse(FlatBufferBuilder builder) { builder.StartObject(1); }
|
||||
public static void AddThread(FlatBufferBuilder builder, int threadOffset) { builder.AddOffset(0, threadOffset, 0); }
|
||||
public static int CreateThreadVector(FlatBufferBuilder builder, int[] data) { builder.StartVector(4, data.Length, 4); for (int i = data.Length - 1; i >= 0; i--) builder.AddOffset(data[i]); return builder.EndVector(); }
|
||||
public static void StartThreadVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); }
|
||||
public static int EndListThreadsResponse(FlatBufferBuilder builder) {
|
||||
int o = builder.EndObject();
|
||||
return o;
|
||||
|
|
|
@ -15,10 +15,11 @@ public enum RequestData : byte
|
|||
GetModuleRequest = 7,
|
||||
ListFunctionsRequest = 8,
|
||||
GetFunctionRequest = 9,
|
||||
StopRequest = 10,
|
||||
BreakRequest = 11,
|
||||
ContinueRequest = 12,
|
||||
StepRequest = 13,
|
||||
ListThreadsRequest = 10,
|
||||
StopRequest = 11,
|
||||
BreakRequest = 12,
|
||||
ContinueRequest = 13,
|
||||
StepRequest = 14,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -15,12 +15,13 @@ public enum ResponseData : byte
|
|||
GetModuleResponse = 7,
|
||||
ListFunctionsResponse = 8,
|
||||
GetFunctionResponse = 9,
|
||||
StopResponse = 10,
|
||||
BreakResponse = 11,
|
||||
ContinueResponse = 12,
|
||||
StepResponse = 13,
|
||||
BreakpointEvent = 14,
|
||||
AccessViolationEvent = 15,
|
||||
ListThreadsResponse = 10,
|
||||
StopResponse = 11,
|
||||
BreakResponse = 12,
|
||||
ContinueResponse = 13,
|
||||
StepResponse = 14,
|
||||
BreakpointEvent = 15,
|
||||
AccessViolationEvent = 16,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -13,10 +13,36 @@ public sealed class Thread : Table {
|
|||
public XObject Object { get { return GetObject(new XObject()); } }
|
||||
public XObject GetObject(XObject obj) { int o = __offset(4); return o != 0 ? obj.__init(o + bb_pos, bb) : null; }
|
||||
public ThreadType Type { get { int o = __offset(6); return o != 0 ? (ThreadType)bb.GetSbyte(o + bb_pos) : (ThreadType)0; } }
|
||||
public uint StackSize { get { int o = __offset(8); return o != 0 ? bb.GetUint(o + bb_pos) : (uint)0; } }
|
||||
public uint XapiThreadStartup { get { int o = __offset(10); return o != 0 ? bb.GetUint(o + bb_pos) : (uint)0; } }
|
||||
public uint StartAddress { get { int o = __offset(12); return o != 0 ? bb.GetUint(o + bb_pos) : (uint)0; } }
|
||||
public uint StartContext { get { int o = __offset(14); return o != 0 ? bb.GetUint(o + bb_pos) : (uint)0; } }
|
||||
public uint CreationFlags { get { int o = __offset(16); return o != 0 ? bb.GetUint(o + bb_pos) : (uint)0; } }
|
||||
public uint TlsAddress { get { int o = __offset(18); return o != 0 ? bb.GetUint(o + bb_pos) : (uint)0; } }
|
||||
public uint PcrAddress { get { int o = __offset(20); return o != 0 ? bb.GetUint(o + bb_pos) : (uint)0; } }
|
||||
public uint ThreadStateAddress { get { int o = __offset(22); return o != 0 ? bb.GetUint(o + bb_pos) : (uint)0; } }
|
||||
public uint ThreadId { get { int o = __offset(24); return o != 0 ? bb.GetUint(o + bb_pos) : (uint)0; } }
|
||||
public string Name { get { int o = __offset(26); return o != 0 ? __string(o + bb_pos) : null; } }
|
||||
public uint Priority { get { int o = __offset(28); return o != 0 ? bb.GetUint(o + bb_pos) : (uint)0; } }
|
||||
public uint Affinity { get { int o = __offset(30); return o != 0 ? bb.GetUint(o + bb_pos) : (uint)0; } }
|
||||
public uint State { get { int o = __offset(32); return o != 0 ? bb.GetUint(o + bb_pos) : (uint)0; } }
|
||||
|
||||
public static void StartThread(FlatBufferBuilder builder) { builder.StartObject(2); }
|
||||
public static void StartThread(FlatBufferBuilder builder) { builder.StartObject(15); }
|
||||
public static void AddObject(FlatBufferBuilder builder, int objectOffset) { builder.AddStruct(0, objectOffset, 0); }
|
||||
public static void AddType(FlatBufferBuilder builder, ThreadType type) { builder.AddSbyte(1, (sbyte)(type), 0); }
|
||||
public static void AddStackSize(FlatBufferBuilder builder, uint stackSize) { builder.AddUint(2, stackSize, 0); }
|
||||
public static void AddXapiThreadStartup(FlatBufferBuilder builder, uint xapiThreadStartup) { builder.AddUint(3, xapiThreadStartup, 0); }
|
||||
public static void AddStartAddress(FlatBufferBuilder builder, uint startAddress) { builder.AddUint(4, startAddress, 0); }
|
||||
public static void AddStartContext(FlatBufferBuilder builder, uint startContext) { builder.AddUint(5, startContext, 0); }
|
||||
public static void AddCreationFlags(FlatBufferBuilder builder, uint creationFlags) { builder.AddUint(6, creationFlags, 0); }
|
||||
public static void AddTlsAddress(FlatBufferBuilder builder, uint tlsAddress) { builder.AddUint(7, tlsAddress, 0); }
|
||||
public static void AddPcrAddress(FlatBufferBuilder builder, uint pcrAddress) { builder.AddUint(8, pcrAddress, 0); }
|
||||
public static void AddThreadStateAddress(FlatBufferBuilder builder, uint threadStateAddress) { builder.AddUint(9, threadStateAddress, 0); }
|
||||
public static void AddThreadId(FlatBufferBuilder builder, uint threadId) { builder.AddUint(10, threadId, 0); }
|
||||
public static void AddName(FlatBufferBuilder builder, int nameOffset) { builder.AddOffset(11, nameOffset, 0); }
|
||||
public static void AddPriority(FlatBufferBuilder builder, uint priority) { builder.AddUint(12, priority, 0); }
|
||||
public static void AddAffinity(FlatBufferBuilder builder, uint affinity) { builder.AddUint(13, affinity, 0); }
|
||||
public static void AddState(FlatBufferBuilder builder, uint state) { builder.AddUint(14, state, 0); }
|
||||
public static int EndThread(FlatBufferBuilder builder) {
|
||||
int o = builder.EndObject();
|
||||
return o;
|
||||
|
|
|
@ -13,6 +13,7 @@ using System.Collections.Generic;
|
|||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using xe.debug.proto;
|
||||
using Xenia.Debug.Utilities;
|
||||
|
||||
namespace Xenia.Debug {
|
||||
|
@ -25,6 +26,23 @@ namespace Xenia.Debug {
|
|||
this.debugger = debugger;
|
||||
}
|
||||
|
||||
public async Task Invalidate() {
|
||||
var fbb = debugger.BeginRequest();
|
||||
ListThreadsRequest.StartListThreadsRequest(fbb);
|
||||
int requestDataOffset = ListThreadsRequest.EndListThreadsRequest(fbb);
|
||||
var response = await debugger.CommitRequest(
|
||||
fbb, RequestData.ListThreadsRequest, requestDataOffset);
|
||||
ListThreadsResponse responseData = new ListThreadsResponse();
|
||||
response.GetResponseData(responseData);
|
||||
|
||||
for (int i = 0; i < responseData.ThreadLength; ++i) {
|
||||
var threadData = responseData.GetThread(i);
|
||||
// threadData.Name;
|
||||
}
|
||||
|
||||
OnChanged();
|
||||
}
|
||||
|
||||
public int Count {
|
||||
get {
|
||||
return threads.Count;
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "xenia/debug/proto/control_generated.h"
|
||||
#include "xenia/debug/proto/messages_generated.h"
|
||||
#include "xenia/debug/proto/modules_generated.h"
|
||||
#include "xenia/debug/proto/threads_generated.h"
|
||||
|
||||
DEFINE_string(debug_session_path, "", "Debug output path.");
|
||||
DEFINE_int32(debug_port, 19000, "Port the debugger listens on.");
|
||||
|
@ -400,6 +401,38 @@ void Debugger::OnMessage(std::vector<uint8_t> buffer) {
|
|||
response_data_offset = response_data.Finish().Union();
|
||||
} break;
|
||||
|
||||
case proto::RequestData_ListThreadsRequest: {
|
||||
response_data_type = proto::ResponseData_ListThreadsResponse;
|
||||
auto threads =
|
||||
emulator()->kernel_state()->object_table()->GetObjectsByType<XThread>(
|
||||
XObject::kTypeThread);
|
||||
std::vector<flatbuffers::Offset<proto::Thread>> thread_list;
|
||||
for (size_t i = 0; i < threads.size(); ++i) {
|
||||
auto& thread = threads[i];
|
||||
auto thread_name_string = fbb.CreateString(thread->name());
|
||||
auto thread_builder = proto::ThreadBuilder(fbb);
|
||||
// thread_builder.add_type();
|
||||
// thread_builder.add_stack_size();
|
||||
// thread_builder.add_xapi_thread_startup();
|
||||
// thread_builder.add_start_address();
|
||||
// thread_builder.add_start_context();
|
||||
// thread_builder.add_creation_flags();
|
||||
thread_builder.add_tls_address(thread->tls_ptr());
|
||||
thread_builder.add_pcr_address(thread->pcr_ptr());
|
||||
thread_builder.add_thread_state_address(thread->thread_state_ptr());
|
||||
thread_builder.add_thread_id(thread->thread_id());
|
||||
thread_builder.add_name(thread_name_string);
|
||||
thread_builder.add_priority(thread->priority());
|
||||
thread_builder.add_affinity(thread->affinity());
|
||||
// thread_builder.add_state(thread->);
|
||||
thread_list.push_back(thread_builder.Finish());
|
||||
}
|
||||
auto threads_offset = fbb.CreateVector(thread_list);
|
||||
auto response_data = proto::ListThreadsResponseBuilder(fbb);
|
||||
response_data.add_thread(threads_offset);
|
||||
response_data_offset = response_data.Finish().Union();
|
||||
} break;
|
||||
|
||||
case proto::RequestData_StopRequest: {
|
||||
response_data_type = proto::ResponseData_StopResponse;
|
||||
auto response_data = proto::StopResponseBuilder(fbb);
|
||||
|
|
|
@ -31,6 +31,8 @@ union RequestData {
|
|||
ListFunctionsRequest,
|
||||
GetFunctionRequest,
|
||||
|
||||
ListThreadsRequest,
|
||||
|
||||
StopRequest,
|
||||
BreakRequest,
|
||||
ContinueRequest,
|
||||
|
@ -55,6 +57,8 @@ union ResponseData {
|
|||
ListFunctionsResponse,
|
||||
GetFunctionResponse,
|
||||
|
||||
ListThreadsResponse,
|
||||
|
||||
StopResponse,
|
||||
BreakResponse,
|
||||
ContinueResponse,
|
||||
|
|
|
@ -91,14 +91,23 @@ enum RequestData {
|
|||
RequestData_GetModuleRequest = 7,
|
||||
RequestData_ListFunctionsRequest = 8,
|
||||
RequestData_GetFunctionRequest = 9,
|
||||
RequestData_StopRequest = 10,
|
||||
RequestData_BreakRequest = 11,
|
||||
RequestData_ContinueRequest = 12,
|
||||
RequestData_StepRequest = 13
|
||||
RequestData_ListThreadsRequest = 10,
|
||||
RequestData_StopRequest = 11,
|
||||
RequestData_BreakRequest = 12,
|
||||
RequestData_ContinueRequest = 13,
|
||||
RequestData_StepRequest = 14
|
||||
};
|
||||
|
||||
inline const char **EnumNamesRequestData() {
|
||||
static const char *names[] = { "NONE", "AttachRequest", "ListBreakpointsRequest", "AddBreakpointsRequest", "UpdateBreakpointsRequest", "RemoveBreakpointsRequest", "ListModulesRequest", "GetModuleRequest", "ListFunctionsRequest", "GetFunctionRequest", "StopRequest", "BreakRequest", "ContinueRequest", "StepRequest", nullptr };
|
||||
static const char *names[] = {
|
||||
"NONE", "AttachRequest",
|
||||
"ListBreakpointsRequest", "AddBreakpointsRequest",
|
||||
"UpdateBreakpointsRequest", "RemoveBreakpointsRequest",
|
||||
"ListModulesRequest", "GetModuleRequest",
|
||||
"ListFunctionsRequest", "GetFunctionRequest",
|
||||
"ListThreadsRequest", "StopRequest",
|
||||
"BreakRequest", "ContinueRequest",
|
||||
"StepRequest", nullptr};
|
||||
return names;
|
||||
}
|
||||
|
||||
|
@ -117,16 +126,26 @@ enum ResponseData {
|
|||
ResponseData_GetModuleResponse = 7,
|
||||
ResponseData_ListFunctionsResponse = 8,
|
||||
ResponseData_GetFunctionResponse = 9,
|
||||
ResponseData_StopResponse = 10,
|
||||
ResponseData_BreakResponse = 11,
|
||||
ResponseData_ContinueResponse = 12,
|
||||
ResponseData_StepResponse = 13,
|
||||
ResponseData_BreakpointEvent = 14,
|
||||
ResponseData_AccessViolationEvent = 15
|
||||
ResponseData_ListThreadsResponse = 10,
|
||||
ResponseData_StopResponse = 11,
|
||||
ResponseData_BreakResponse = 12,
|
||||
ResponseData_ContinueResponse = 13,
|
||||
ResponseData_StepResponse = 14,
|
||||
ResponseData_BreakpointEvent = 15,
|
||||
ResponseData_AccessViolationEvent = 16
|
||||
};
|
||||
|
||||
inline const char **EnumNamesResponseData() {
|
||||
static const char *names[] = { "NONE", "AttachResponse", "ListBreakpointsResponse", "AddBreakpointsResponse", "UpdateBreakpointsResponse", "RemoveBreakpointsResponse", "ListModulesResponse", "GetModuleResponse", "ListFunctionsResponse", "GetFunctionResponse", "StopResponse", "BreakResponse", "ContinueResponse", "StepResponse", "BreakpointEvent", "AccessViolationEvent", nullptr };
|
||||
static const char *names[] = {
|
||||
"NONE", "AttachResponse",
|
||||
"ListBreakpointsResponse", "AddBreakpointsResponse",
|
||||
"UpdateBreakpointsResponse", "RemoveBreakpointsResponse",
|
||||
"ListModulesResponse", "GetModuleResponse",
|
||||
"ListFunctionsResponse", "GetFunctionResponse",
|
||||
"ListThreadsResponse", "StopResponse",
|
||||
"BreakResponse", "ContinueResponse",
|
||||
"StepResponse", "BreakpointEvent",
|
||||
"AccessViolationEvent", nullptr};
|
||||
return names;
|
||||
}
|
||||
|
||||
|
@ -304,6 +323,10 @@ inline bool VerifyRequestData(flatbuffers::Verifier &verifier, const void *union
|
|||
case RequestData_GetModuleRequest: return verifier.VerifyTable(reinterpret_cast<const xe::debug::proto::GetModuleRequest *>(union_obj));
|
||||
case RequestData_ListFunctionsRequest: return verifier.VerifyTable(reinterpret_cast<const xe::debug::proto::ListFunctionsRequest *>(union_obj));
|
||||
case RequestData_GetFunctionRequest: return verifier.VerifyTable(reinterpret_cast<const xe::debug::proto::GetFunctionRequest *>(union_obj));
|
||||
case RequestData_ListThreadsRequest:
|
||||
return verifier.VerifyTable(
|
||||
reinterpret_cast<const xe::debug::proto::ListThreadsRequest *>(
|
||||
union_obj));
|
||||
case RequestData_StopRequest: return verifier.VerifyTable(reinterpret_cast<const xe::debug::proto::StopRequest *>(union_obj));
|
||||
case RequestData_BreakRequest: return verifier.VerifyTable(reinterpret_cast<const xe::debug::proto::BreakRequest *>(union_obj));
|
||||
case RequestData_ContinueRequest: return verifier.VerifyTable(reinterpret_cast<const xe::debug::proto::ContinueRequest *>(union_obj));
|
||||
|
@ -324,6 +347,10 @@ inline bool VerifyResponseData(flatbuffers::Verifier &verifier, const void *unio
|
|||
case ResponseData_GetModuleResponse: return verifier.VerifyTable(reinterpret_cast<const xe::debug::proto::GetModuleResponse *>(union_obj));
|
||||
case ResponseData_ListFunctionsResponse: return verifier.VerifyTable(reinterpret_cast<const xe::debug::proto::ListFunctionsResponse *>(union_obj));
|
||||
case ResponseData_GetFunctionResponse: return verifier.VerifyTable(reinterpret_cast<const xe::debug::proto::GetFunctionResponse *>(union_obj));
|
||||
case ResponseData_ListThreadsResponse:
|
||||
return verifier.VerifyTable(
|
||||
reinterpret_cast<const xe::debug::proto::ListThreadsResponse *>(
|
||||
union_obj));
|
||||
case ResponseData_StopResponse: return verifier.VerifyTable(reinterpret_cast<const xe::debug::proto::StopResponse *>(union_obj));
|
||||
case ResponseData_BreakResponse: return verifier.VerifyTable(reinterpret_cast<const xe::debug::proto::BreakResponse *>(union_obj));
|
||||
case ResponseData_ContinueResponse: return verifier.VerifyTable(reinterpret_cast<const xe::debug::proto::ContinueResponse *>(union_obj));
|
||||
|
|
|
@ -13,9 +13,26 @@ table Thread {
|
|||
|
||||
// module_id:uint;
|
||||
// creation callstack
|
||||
|
||||
stack_size:uint;
|
||||
xapi_thread_startup:uint;
|
||||
start_address:uint;
|
||||
start_context:uint;
|
||||
creation_flags:uint;
|
||||
|
||||
tls_address:uint;
|
||||
pcr_address:uint;
|
||||
thread_state_address:uint;
|
||||
thread_id:uint;
|
||||
name:string;
|
||||
|
||||
priority:uint;
|
||||
affinity:uint;
|
||||
state:uint;
|
||||
}
|
||||
|
||||
table ListThreadsRequest {
|
||||
}
|
||||
table ListThreadsResponse {
|
||||
thread:[Thread];
|
||||
}
|
||||
|
|
|
@ -36,10 +36,39 @@ inline const char *EnumNameThreadType(ThreadType e) { return EnumNamesThreadType
|
|||
struct Thread FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
const xe::debug::proto::XObject *object() const { return GetStruct<const xe::debug::proto::XObject *>(4); }
|
||||
ThreadType type() const { return static_cast<ThreadType>(GetField<int8_t>(6, 0)); }
|
||||
uint32_t stack_size() const { return GetField<uint32_t>(8, 0); }
|
||||
uint32_t xapi_thread_startup() const { return GetField<uint32_t>(10, 0); }
|
||||
uint32_t start_address() const { return GetField<uint32_t>(12, 0); }
|
||||
uint32_t start_context() const { return GetField<uint32_t>(14, 0); }
|
||||
uint32_t creation_flags() const { return GetField<uint32_t>(16, 0); }
|
||||
uint32_t tls_address() const { return GetField<uint32_t>(18, 0); }
|
||||
uint32_t pcr_address() const { return GetField<uint32_t>(20, 0); }
|
||||
uint32_t thread_state_address() const { return GetField<uint32_t>(22, 0); }
|
||||
uint32_t thread_id() const { return GetField<uint32_t>(24, 0); }
|
||||
const flatbuffers::String *name() const {
|
||||
return GetPointer<const flatbuffers::String *>(26);
|
||||
}
|
||||
uint32_t priority() const { return GetField<uint32_t>(28, 0); }
|
||||
uint32_t affinity() const { return GetField<uint32_t>(30, 0); }
|
||||
uint32_t state() const { return GetField<uint32_t>(32, 0); }
|
||||
bool Verify(flatbuffers::Verifier &verifier) const {
|
||||
return VerifyTableStart(verifier) &&
|
||||
VerifyField<xe::debug::proto::XObject>(verifier, 4 /* object */) &&
|
||||
VerifyField<int8_t>(verifier, 6 /* type */) &&
|
||||
VerifyField<uint32_t>(verifier, 8 /* stack_size */) &&
|
||||
VerifyField<uint32_t>(verifier, 10 /* xapi_thread_startup */) &&
|
||||
VerifyField<uint32_t>(verifier, 12 /* start_address */) &&
|
||||
VerifyField<uint32_t>(verifier, 14 /* start_context */) &&
|
||||
VerifyField<uint32_t>(verifier, 16 /* creation_flags */) &&
|
||||
VerifyField<uint32_t>(verifier, 18 /* tls_address */) &&
|
||||
VerifyField<uint32_t>(verifier, 20 /* pcr_address */) &&
|
||||
VerifyField<uint32_t>(verifier, 22 /* thread_state_address */) &&
|
||||
VerifyField<uint32_t>(verifier, 24 /* thread_id */) &&
|
||||
VerifyField<flatbuffers::uoffset_t>(verifier, 26 /* name */) &&
|
||||
verifier.Verify(name()) &&
|
||||
VerifyField<uint32_t>(verifier, 28 /* priority */) &&
|
||||
VerifyField<uint32_t>(verifier, 30 /* affinity */) &&
|
||||
VerifyField<uint32_t>(verifier, 32 /* state */) &&
|
||||
verifier.EndTable();
|
||||
}
|
||||
};
|
||||
|
@ -49,18 +78,75 @@ struct ThreadBuilder {
|
|||
flatbuffers::uoffset_t start_;
|
||||
void add_object(const xe::debug::proto::XObject *object) { fbb_.AddStruct(4, object); }
|
||||
void add_type(ThreadType type) { fbb_.AddElement<int8_t>(6, static_cast<int8_t>(type), 0); }
|
||||
void add_stack_size(uint32_t stack_size) {
|
||||
fbb_.AddElement<uint32_t>(8, stack_size, 0);
|
||||
}
|
||||
void add_xapi_thread_startup(uint32_t xapi_thread_startup) {
|
||||
fbb_.AddElement<uint32_t>(10, xapi_thread_startup, 0);
|
||||
}
|
||||
void add_start_address(uint32_t start_address) {
|
||||
fbb_.AddElement<uint32_t>(12, start_address, 0);
|
||||
}
|
||||
void add_start_context(uint32_t start_context) {
|
||||
fbb_.AddElement<uint32_t>(14, start_context, 0);
|
||||
}
|
||||
void add_creation_flags(uint32_t creation_flags) {
|
||||
fbb_.AddElement<uint32_t>(16, creation_flags, 0);
|
||||
}
|
||||
void add_tls_address(uint32_t tls_address) {
|
||||
fbb_.AddElement<uint32_t>(18, tls_address, 0);
|
||||
}
|
||||
void add_pcr_address(uint32_t pcr_address) {
|
||||
fbb_.AddElement<uint32_t>(20, pcr_address, 0);
|
||||
}
|
||||
void add_thread_state_address(uint32_t thread_state_address) {
|
||||
fbb_.AddElement<uint32_t>(22, thread_state_address, 0);
|
||||
}
|
||||
void add_thread_id(uint32_t thread_id) {
|
||||
fbb_.AddElement<uint32_t>(24, thread_id, 0);
|
||||
}
|
||||
void add_name(flatbuffers::Offset<flatbuffers::String> name) {
|
||||
fbb_.AddOffset(26, name);
|
||||
}
|
||||
void add_priority(uint32_t priority) {
|
||||
fbb_.AddElement<uint32_t>(28, priority, 0);
|
||||
}
|
||||
void add_affinity(uint32_t affinity) {
|
||||
fbb_.AddElement<uint32_t>(30, affinity, 0);
|
||||
}
|
||||
void add_state(uint32_t state) { fbb_.AddElement<uint32_t>(32, state, 0); }
|
||||
ThreadBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); }
|
||||
ThreadBuilder &operator=(const ThreadBuilder &);
|
||||
flatbuffers::Offset<Thread> Finish() {
|
||||
auto o = flatbuffers::Offset<Thread>(fbb_.EndTable(start_, 2));
|
||||
auto o = flatbuffers::Offset<Thread>(fbb_.EndTable(start_, 15));
|
||||
return o;
|
||||
}
|
||||
};
|
||||
|
||||
inline flatbuffers::Offset<Thread> CreateThread(flatbuffers::FlatBufferBuilder &_fbb,
|
||||
inline flatbuffers::Offset<Thread> CreateThread(
|
||||
flatbuffers::FlatBufferBuilder &_fbb,
|
||||
const xe::debug::proto::XObject *object = 0,
|
||||
ThreadType type = ThreadType_Kernel) {
|
||||
ThreadType type = ThreadType_Kernel, uint32_t stack_size = 0,
|
||||
uint32_t xapi_thread_startup = 0, uint32_t start_address = 0,
|
||||
uint32_t start_context = 0, uint32_t creation_flags = 0,
|
||||
uint32_t tls_address = 0, uint32_t pcr_address = 0,
|
||||
uint32_t thread_state_address = 0, uint32_t thread_id = 0,
|
||||
flatbuffers::Offset<flatbuffers::String> name = 0, uint32_t priority = 0,
|
||||
uint32_t affinity = 0, uint32_t state = 0) {
|
||||
ThreadBuilder builder_(_fbb);
|
||||
builder_.add_state(state);
|
||||
builder_.add_affinity(affinity);
|
||||
builder_.add_priority(priority);
|
||||
builder_.add_name(name);
|
||||
builder_.add_thread_id(thread_id);
|
||||
builder_.add_thread_state_address(thread_state_address);
|
||||
builder_.add_pcr_address(pcr_address);
|
||||
builder_.add_tls_address(tls_address);
|
||||
builder_.add_creation_flags(creation_flags);
|
||||
builder_.add_start_context(start_context);
|
||||
builder_.add_start_address(start_address);
|
||||
builder_.add_xapi_thread_startup(xapi_thread_startup);
|
||||
builder_.add_stack_size(stack_size);
|
||||
builder_.add_object(object);
|
||||
builder_.add_type(type);
|
||||
return builder_.Finish();
|
||||
|
@ -90,25 +176,39 @@ inline flatbuffers::Offset<ListThreadsRequest> CreateListThreadsRequest(flatbuff
|
|||
}
|
||||
|
||||
struct ListThreadsResponse FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
const flatbuffers::Vector<flatbuffers::Offset<Thread>> *thread() const {
|
||||
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<Thread>> *>(
|
||||
4);
|
||||
}
|
||||
bool Verify(flatbuffers::Verifier &verifier) const {
|
||||
return VerifyTableStart(verifier) &&
|
||||
verifier.EndTable();
|
||||
VerifyField<flatbuffers::uoffset_t>(verifier, 4 /* thread */) &&
|
||||
verifier.Verify(thread()) &&
|
||||
verifier.VerifyVectorOfTables(thread()) && verifier.EndTable();
|
||||
}
|
||||
};
|
||||
|
||||
struct ListThreadsResponseBuilder {
|
||||
flatbuffers::FlatBufferBuilder &fbb_;
|
||||
flatbuffers::uoffset_t start_;
|
||||
void add_thread(flatbuffers::Offset<
|
||||
flatbuffers::Vector<flatbuffers::Offset<Thread>>> thread) {
|
||||
fbb_.AddOffset(4, thread);
|
||||
}
|
||||
ListThreadsResponseBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); }
|
||||
ListThreadsResponseBuilder &operator=(const ListThreadsResponseBuilder &);
|
||||
flatbuffers::Offset<ListThreadsResponse> Finish() {
|
||||
auto o = flatbuffers::Offset<ListThreadsResponse>(fbb_.EndTable(start_, 0));
|
||||
auto o = flatbuffers::Offset<ListThreadsResponse>(fbb_.EndTable(start_, 1));
|
||||
return o;
|
||||
}
|
||||
};
|
||||
|
||||
inline flatbuffers::Offset<ListThreadsResponse> CreateListThreadsResponse(flatbuffers::FlatBufferBuilder &_fbb) {
|
||||
inline flatbuffers::Offset<ListThreadsResponse> CreateListThreadsResponse(
|
||||
flatbuffers::FlatBufferBuilder &_fbb,
|
||||
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Thread>>>
|
||||
thread = 0) {
|
||||
ListThreadsResponseBuilder builder_(_fbb);
|
||||
builder_.add_thread(thread);
|
||||
return builder_.Finish();
|
||||
}
|
||||
|
||||
|
|
|
@ -46,6 +46,8 @@ XThread::XThread(KernelState* kernel_state, uint32_t stack_size,
|
|||
pcr_address_(0),
|
||||
thread_state_address_(0),
|
||||
thread_state_(0),
|
||||
priority_(0),
|
||||
affinity_(0),
|
||||
irql_(0) {
|
||||
creation_params_.stack_size = stack_size;
|
||||
creation_params_.xapi_thread_startup = xapi_thread_startup;
|
||||
|
@ -613,6 +615,7 @@ void XThread::RundownAPCs() {
|
|||
int32_t XThread::QueryPriority() { return GetThreadPriority(thread_handle_); }
|
||||
|
||||
void XThread::SetPriority(int32_t increment) {
|
||||
priority_ = increment;
|
||||
int target_priority = 0;
|
||||
if (increment > 0x22) {
|
||||
target_priority = THREAD_PRIORITY_HIGHEST;
|
||||
|
@ -647,11 +650,17 @@ void XThread::SetAffinity(uint32_t affinity) {
|
|||
XELOGW("Too few processors - scheduling will be wonky");
|
||||
}
|
||||
SetActiveCpu(GetFakeCpuNumber(affinity));
|
||||
affinity_ = affinity;
|
||||
if (!FLAGS_ignore_thread_affinities) {
|
||||
SetThreadAffinityMask(reinterpret_cast<HANDLE>(thread_handle_), affinity);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t XThread::active_cpu() const {
|
||||
uint8_t* pcr = memory()->TranslateVirtual(pcr_address_);
|
||||
return xe::load_and_swap<uint8_t>(pcr + 0x10C);
|
||||
}
|
||||
|
||||
void XThread::SetActiveCpu(uint32_t cpu_index) {
|
||||
uint8_t* pcr = memory()->TranslateVirtual(pcr_address_);
|
||||
xe::store_and_swap<uint8_t>(pcr + 0x10C, cpu_index);
|
||||
|
|
|
@ -85,6 +85,7 @@ class XThread : public XObject {
|
|||
static uint32_t GetCurrentThreadHandle();
|
||||
static uint32_t GetCurrentThreadId(const uint8_t* pcr);
|
||||
|
||||
uint32_t tls_ptr() const { return tls_address_; }
|
||||
uint32_t pcr_ptr() const { return pcr_address_; }
|
||||
uint32_t thread_state_ptr() const { return thread_state_address_; }
|
||||
|
||||
|
@ -112,9 +113,12 @@ class XThread : public XObject {
|
|||
void EnqueueApc(uint32_t normal_routine, uint32_t normal_context,
|
||||
uint32_t arg1, uint32_t arg2);
|
||||
|
||||
int32_t priority() const { return priority_; }
|
||||
int32_t QueryPriority();
|
||||
void SetPriority(int32_t increment);
|
||||
uint32_t affinity() const { return affinity_; }
|
||||
void SetAffinity(uint32_t affinity);
|
||||
uint32_t active_cpu() const;
|
||||
void SetActiveCpu(uint32_t cpu_index);
|
||||
|
||||
X_STATUS Resume(uint32_t* out_suspend_count = nullptr);
|
||||
|
@ -151,6 +155,9 @@ class XThread : public XObject {
|
|||
|
||||
std::string name_;
|
||||
|
||||
int32_t priority_;
|
||||
uint32_t affinity_;
|
||||
|
||||
std::atomic<uint32_t> irql_;
|
||||
xe::mutex apc_lock_;
|
||||
NativeList* apc_list_;
|
||||
|
|
Loading…
Reference in New Issue