mirror of
https://github.com/xenia-project/xenia.git
synced 2025-12-06 07:12:03 +01:00
Merge pull request #106 from Bo98/canary_burnout5_pr1
CPU threading improvements, Kernel game region improvements
This commit is contained in:
commit
8c43160fc6
|
|
@ -30,7 +30,7 @@ namespace x64 {
|
||||||
bool trace_enabled = true;
|
bool trace_enabled = true;
|
||||||
|
|
||||||
#define THREAD_MATCH \
|
#define THREAD_MATCH \
|
||||||
(!TARGET_THREAD || thread_state->thread_id() == TARGET_THREAD)
|
(!TARGET_THREAD || ppc_context->thread_id == TARGET_THREAD)
|
||||||
#define IFLUSH()
|
#define IFLUSH()
|
||||||
#define IPRINT(s) \
|
#define IPRINT(s) \
|
||||||
if (trace_enabled && THREAD_MATCH) \
|
if (trace_enabled && THREAD_MATCH) \
|
||||||
|
|
@ -52,41 +52,41 @@ uint32_t GetTracingMode() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void TraceString(void* raw_context, const char* str) {
|
void TraceString(void* raw_context, const char* str) {
|
||||||
auto thread_state = *reinterpret_cast<ThreadState**>(raw_context);
|
auto ppc_context = reinterpret_cast<ppc::PPCContext*>(raw_context);
|
||||||
IPRINT(str);
|
IPRINT(str);
|
||||||
IFLUSH();
|
IFLUSH();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TraceContextLoadI8(void* raw_context, uint64_t offset, uint8_t value) {
|
void TraceContextLoadI8(void* raw_context, uint64_t offset, uint8_t value) {
|
||||||
auto thread_state = *reinterpret_cast<ThreadState**>(raw_context);
|
auto ppc_context = reinterpret_cast<ppc::PPCContext*>(raw_context);
|
||||||
DPRINT("{} ({:X}) = ctx i8 +{}\n", (int8_t)value, value, offset);
|
DPRINT("{} ({:X}) = ctx i8 +{}\n", (int8_t)value, value, offset);
|
||||||
}
|
}
|
||||||
void TraceContextLoadI16(void* raw_context, uint64_t offset, uint16_t value) {
|
void TraceContextLoadI16(void* raw_context, uint64_t offset, uint16_t value) {
|
||||||
auto thread_state = *reinterpret_cast<ThreadState**>(raw_context);
|
auto ppc_context = reinterpret_cast<ppc::PPCContext*>(raw_context);
|
||||||
DPRINT("{} ({:X}) = ctx i16 +{}\n", (int16_t)value, value, offset);
|
DPRINT("{} ({:X}) = ctx i16 +{}\n", (int16_t)value, value, offset);
|
||||||
}
|
}
|
||||||
void TraceContextLoadI32(void* raw_context, uint64_t offset, uint32_t value) {
|
void TraceContextLoadI32(void* raw_context, uint64_t offset, uint32_t value) {
|
||||||
auto thread_state = *reinterpret_cast<ThreadState**>(raw_context);
|
auto ppc_context = reinterpret_cast<ppc::PPCContext*>(raw_context);
|
||||||
DPRINT("{} ({:X}) = ctx i32 +{}\n", (int32_t)value, value, offset);
|
DPRINT("{} ({:X}) = ctx i32 +{}\n", (int32_t)value, value, offset);
|
||||||
}
|
}
|
||||||
void TraceContextLoadI64(void* raw_context, uint64_t offset, uint64_t value) {
|
void TraceContextLoadI64(void* raw_context, uint64_t offset, uint64_t value) {
|
||||||
auto thread_state = *reinterpret_cast<ThreadState**>(raw_context);
|
auto ppc_context = reinterpret_cast<ppc::PPCContext*>(raw_context);
|
||||||
DPRINT("{} ({:X}) = ctx i64 +{}\n", (int64_t)value, value, offset);
|
DPRINT("{} ({:X}) = ctx i64 +{}\n", (int64_t)value, value, offset);
|
||||||
}
|
}
|
||||||
void TraceContextLoadF32(void* raw_context, uint64_t offset, __m128 value) {
|
void TraceContextLoadF32(void* raw_context, uint64_t offset, __m128 value) {
|
||||||
auto thread_state = *reinterpret_cast<ThreadState**>(raw_context);
|
auto ppc_context = reinterpret_cast<ppc::PPCContext*>(raw_context);
|
||||||
DPRINT("{} ({:X}) = ctx f32 +{}\n", xe::m128_f32<0>(value),
|
DPRINT("{} ({:X}) = ctx f32 +{}\n", xe::m128_f32<0>(value),
|
||||||
xe::m128_i32<0>(value), offset);
|
xe::m128_i32<0>(value), offset);
|
||||||
}
|
}
|
||||||
void TraceContextLoadF64(void* raw_context, uint64_t offset,
|
void TraceContextLoadF64(void* raw_context, uint64_t offset,
|
||||||
const double* value) {
|
const double* value) {
|
||||||
auto thread_state = *reinterpret_cast<ThreadState**>(raw_context);
|
auto ppc_context = reinterpret_cast<ppc::PPCContext*>(raw_context);
|
||||||
auto v = _mm_loadu_pd(value);
|
auto v = _mm_loadu_pd(value);
|
||||||
DPRINT("{} ({:X}) = ctx f64 +{}\n", xe::m128_f64<0>(v), xe::m128_i64<0>(v),
|
DPRINT("{} ({:X}) = ctx f64 +{}\n", xe::m128_f64<0>(v), xe::m128_i64<0>(v),
|
||||||
offset);
|
offset);
|
||||||
}
|
}
|
||||||
void TraceContextLoadV128(void* raw_context, uint64_t offset, __m128 value) {
|
void TraceContextLoadV128(void* raw_context, uint64_t offset, __m128 value) {
|
||||||
auto thread_state = *reinterpret_cast<ThreadState**>(raw_context);
|
auto ppc_context = reinterpret_cast<ppc::PPCContext*>(raw_context);
|
||||||
DPRINT("[{}, {}, {}, {}] [{:08X}, {:08X}, {:08X}, {:08X}] = ctx v128 +{}\n",
|
DPRINT("[{}, {}, {}, {}] [{:08X}, {:08X}, {:08X}, {:08X}] = ctx v128 +{}\n",
|
||||||
xe::m128_f32<0>(value), xe::m128_f32<1>(value), xe::m128_f32<2>(value),
|
xe::m128_f32<0>(value), xe::m128_f32<1>(value), xe::m128_f32<2>(value),
|
||||||
xe::m128_f32<3>(value), xe::m128_i32<0>(value), xe::m128_i32<1>(value),
|
xe::m128_f32<3>(value), xe::m128_i32<0>(value), xe::m128_i32<1>(value),
|
||||||
|
|
@ -94,35 +94,35 @@ void TraceContextLoadV128(void* raw_context, uint64_t offset, __m128 value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void TraceContextStoreI8(void* raw_context, uint64_t offset, uint8_t value) {
|
void TraceContextStoreI8(void* raw_context, uint64_t offset, uint8_t value) {
|
||||||
auto thread_state = *reinterpret_cast<ThreadState**>(raw_context);
|
auto ppc_context = reinterpret_cast<ppc::PPCContext*>(raw_context);
|
||||||
DPRINT("ctx i8 +{} = {} ({:X})\n", offset, (int8_t)value, value);
|
DPRINT("ctx i8 +{} = {} ({:X})\n", offset, (int8_t)value, value);
|
||||||
}
|
}
|
||||||
void TraceContextStoreI16(void* raw_context, uint64_t offset, uint16_t value) {
|
void TraceContextStoreI16(void* raw_context, uint64_t offset, uint16_t value) {
|
||||||
auto thread_state = *reinterpret_cast<ThreadState**>(raw_context);
|
auto ppc_context = reinterpret_cast<ppc::PPCContext*>(raw_context);
|
||||||
DPRINT("ctx i16 +{} = {} ({:X})\n", offset, (int16_t)value, value);
|
DPRINT("ctx i16 +{} = {} ({:X})\n", offset, (int16_t)value, value);
|
||||||
}
|
}
|
||||||
void TraceContextStoreI32(void* raw_context, uint64_t offset, uint32_t value) {
|
void TraceContextStoreI32(void* raw_context, uint64_t offset, uint32_t value) {
|
||||||
auto thread_state = *reinterpret_cast<ThreadState**>(raw_context);
|
auto ppc_context = reinterpret_cast<ppc::PPCContext*>(raw_context);
|
||||||
DPRINT("ctx i32 +{} = {} ({:X})\n", offset, (int32_t)value, value);
|
DPRINT("ctx i32 +{} = {} ({:X})\n", offset, (int32_t)value, value);
|
||||||
}
|
}
|
||||||
void TraceContextStoreI64(void* raw_context, uint64_t offset, uint64_t value) {
|
void TraceContextStoreI64(void* raw_context, uint64_t offset, uint64_t value) {
|
||||||
auto thread_state = *reinterpret_cast<ThreadState**>(raw_context);
|
auto ppc_context = reinterpret_cast<ppc::PPCContext*>(raw_context);
|
||||||
DPRINT("ctx i64 +{} = {} ({:X})\n", offset, (int64_t)value, value);
|
DPRINT("ctx i64 +{} = {} ({:X})\n", offset, (int64_t)value, value);
|
||||||
}
|
}
|
||||||
void TraceContextStoreF32(void* raw_context, uint64_t offset, __m128 value) {
|
void TraceContextStoreF32(void* raw_context, uint64_t offset, __m128 value) {
|
||||||
auto thread_state = *reinterpret_cast<ThreadState**>(raw_context);
|
auto ppc_context = reinterpret_cast<ppc::PPCContext*>(raw_context);
|
||||||
DPRINT("ctx f32 +{} = {} ({:X})\n", offset, xe::m128_f32<0>(value),
|
DPRINT("ctx f32 +{} = {} ({:X})\n", offset, xe::m128_f32<0>(value),
|
||||||
xe::m128_i32<0>(value));
|
xe::m128_i32<0>(value));
|
||||||
}
|
}
|
||||||
void TraceContextStoreF64(void* raw_context, uint64_t offset,
|
void TraceContextStoreF64(void* raw_context, uint64_t offset,
|
||||||
const double* value) {
|
const double* value) {
|
||||||
auto thread_state = *reinterpret_cast<ThreadState**>(raw_context);
|
auto ppc_context = reinterpret_cast<ppc::PPCContext*>(raw_context);
|
||||||
auto v = _mm_loadu_pd(value);
|
auto v = _mm_loadu_pd(value);
|
||||||
DPRINT("ctx f64 +{} = {} ({:X})\n", offset, xe::m128_f64<0>(v),
|
DPRINT("ctx f64 +{} = {} ({:X})\n", offset, xe::m128_f64<0>(v),
|
||||||
xe::m128_i64<0>(v));
|
xe::m128_i64<0>(v));
|
||||||
}
|
}
|
||||||
void TraceContextStoreV128(void* raw_context, uint64_t offset, __m128 value) {
|
void TraceContextStoreV128(void* raw_context, uint64_t offset, __m128 value) {
|
||||||
auto thread_state = *reinterpret_cast<ThreadState**>(raw_context);
|
auto ppc_context = reinterpret_cast<ppc::PPCContext*>(raw_context);
|
||||||
DPRINT("ctx v128 +{} = [{}, {}, {}, {}] [{:08X}, {:08X}, {:08X}, {:08X}]\n",
|
DPRINT("ctx v128 +{} = [{}, {}, {}, {}] [{:08X}, {:08X}, {:08X}, {:08X}]\n",
|
||||||
offset, xe::m128_f32<0>(value), xe::m128_f32<1>(value),
|
offset, xe::m128_f32<0>(value), xe::m128_f32<1>(value),
|
||||||
xe::m128_f32<2>(value), xe::m128_f32<3>(value), xe::m128_i32<0>(value),
|
xe::m128_f32<2>(value), xe::m128_f32<3>(value), xe::m128_i32<0>(value),
|
||||||
|
|
@ -131,33 +131,33 @@ void TraceContextStoreV128(void* raw_context, uint64_t offset, __m128 value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void TraceMemoryLoadI8(void* raw_context, uint32_t address, uint8_t value) {
|
void TraceMemoryLoadI8(void* raw_context, uint32_t address, uint8_t value) {
|
||||||
auto thread_state = *reinterpret_cast<ThreadState**>(raw_context);
|
auto ppc_context = reinterpret_cast<ppc::PPCContext*>(raw_context);
|
||||||
DPRINT("{} ({:X}) = load.i8 {:08X}\n", (int8_t)value, value, address);
|
DPRINT("{} ({:X}) = load.i8 {:08X}\n", (int8_t)value, value, address);
|
||||||
}
|
}
|
||||||
void TraceMemoryLoadI16(void* raw_context, uint32_t address, uint16_t value) {
|
void TraceMemoryLoadI16(void* raw_context, uint32_t address, uint16_t value) {
|
||||||
auto thread_state = *reinterpret_cast<ThreadState**>(raw_context);
|
auto ppc_context = reinterpret_cast<ppc::PPCContext*>(raw_context);
|
||||||
DPRINT("{} ({:X}) = load.i16 {:08X}\n", (int16_t)value, value, address);
|
DPRINT("{} ({:X}) = load.i16 {:08X}\n", (int16_t)value, value, address);
|
||||||
}
|
}
|
||||||
void TraceMemoryLoadI32(void* raw_context, uint32_t address, uint32_t value) {
|
void TraceMemoryLoadI32(void* raw_context, uint32_t address, uint32_t value) {
|
||||||
auto thread_state = *reinterpret_cast<ThreadState**>(raw_context);
|
auto ppc_context = reinterpret_cast<ppc::PPCContext*>(raw_context);
|
||||||
DPRINT("{} ({:X}) = load.i32 {:08X}\n", (int32_t)value, value, address);
|
DPRINT("{} ({:X}) = load.i32 {:08X}\n", (int32_t)value, value, address);
|
||||||
}
|
}
|
||||||
void TraceMemoryLoadI64(void* raw_context, uint32_t address, uint64_t value) {
|
void TraceMemoryLoadI64(void* raw_context, uint32_t address, uint64_t value) {
|
||||||
auto thread_state = *reinterpret_cast<ThreadState**>(raw_context);
|
auto ppc_context = reinterpret_cast<ppc::PPCContext*>(raw_context);
|
||||||
DPRINT("{} ({:X}) = load.i64 {:08X}\n", (int64_t)value, value, address);
|
DPRINT("{} ({:X}) = load.i64 {:08X}\n", (int64_t)value, value, address);
|
||||||
}
|
}
|
||||||
void TraceMemoryLoadF32(void* raw_context, uint32_t address, __m128 value) {
|
void TraceMemoryLoadF32(void* raw_context, uint32_t address, __m128 value) {
|
||||||
auto thread_state = *reinterpret_cast<ThreadState**>(raw_context);
|
auto ppc_context = reinterpret_cast<ppc::PPCContext*>(raw_context);
|
||||||
DPRINT("{} ({:X}) = load.f32 {:08X}\n", xe::m128_f32<0>(value),
|
DPRINT("{} ({:X}) = load.f32 {:08X}\n", xe::m128_f32<0>(value),
|
||||||
xe::m128_i32<0>(value), address);
|
xe::m128_i32<0>(value), address);
|
||||||
}
|
}
|
||||||
void TraceMemoryLoadF64(void* raw_context, uint32_t address, __m128 value) {
|
void TraceMemoryLoadF64(void* raw_context, uint32_t address, __m128 value) {
|
||||||
auto thread_state = *reinterpret_cast<ThreadState**>(raw_context);
|
auto ppc_context = reinterpret_cast<ppc::PPCContext*>(raw_context);
|
||||||
DPRINT("{} ({:X}) = load.f64 {:08X}\n", xe::m128_f64<0>(value),
|
DPRINT("{} ({:X}) = load.f64 {:08X}\n", xe::m128_f64<0>(value),
|
||||||
xe::m128_i64<0>(value), address);
|
xe::m128_i64<0>(value), address);
|
||||||
}
|
}
|
||||||
void TraceMemoryLoadV128(void* raw_context, uint32_t address, __m128 value) {
|
void TraceMemoryLoadV128(void* raw_context, uint32_t address, __m128 value) {
|
||||||
auto thread_state = *reinterpret_cast<ThreadState**>(raw_context);
|
auto ppc_context = reinterpret_cast<ppc::PPCContext*>(raw_context);
|
||||||
DPRINT(
|
DPRINT(
|
||||||
"[{}, {}, {}, {}] [{:08X}, {:08X}, {:08X}, {:08X}] = load.v128 {:08X}\n",
|
"[{}, {}, {}, {}] [{:08X}, {:08X}, {:08X}, {:08X}] = load.v128 {:08X}\n",
|
||||||
xe::m128_f32<0>(value), xe::m128_f32<1>(value), xe::m128_f32<2>(value),
|
xe::m128_f32<0>(value), xe::m128_f32<1>(value), xe::m128_f32<2>(value),
|
||||||
|
|
@ -166,33 +166,33 @@ void TraceMemoryLoadV128(void* raw_context, uint32_t address, __m128 value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void TraceMemoryStoreI8(void* raw_context, uint32_t address, uint8_t value) {
|
void TraceMemoryStoreI8(void* raw_context, uint32_t address, uint8_t value) {
|
||||||
auto thread_state = *reinterpret_cast<ThreadState**>(raw_context);
|
auto ppc_context = reinterpret_cast<ppc::PPCContext*>(raw_context);
|
||||||
DPRINT("store.i8 {:08X} = {} ({:X})\n", address, (int8_t)value, value);
|
DPRINT("store.i8 {:08X} = {} ({:X})\n", address, (int8_t)value, value);
|
||||||
}
|
}
|
||||||
void TraceMemoryStoreI16(void* raw_context, uint32_t address, uint16_t value) {
|
void TraceMemoryStoreI16(void* raw_context, uint32_t address, uint16_t value) {
|
||||||
auto thread_state = *reinterpret_cast<ThreadState**>(raw_context);
|
auto ppc_context = reinterpret_cast<ppc::PPCContext*>(raw_context);
|
||||||
DPRINT("store.i16 {:08X} = {} ({:X})\n", address, (int16_t)value, value);
|
DPRINT("store.i16 {:08X} = {} ({:X})\n", address, (int16_t)value, value);
|
||||||
}
|
}
|
||||||
void TraceMemoryStoreI32(void* raw_context, uint32_t address, uint32_t value) {
|
void TraceMemoryStoreI32(void* raw_context, uint32_t address, uint32_t value) {
|
||||||
auto thread_state = *reinterpret_cast<ThreadState**>(raw_context);
|
auto ppc_context = reinterpret_cast<ppc::PPCContext*>(raw_context);
|
||||||
DPRINT("store.i32 {:08X} = {} ({:X})\n", address, (int32_t)value, value);
|
DPRINT("store.i32 {:08X} = {} ({:X})\n", address, (int32_t)value, value);
|
||||||
}
|
}
|
||||||
void TraceMemoryStoreI64(void* raw_context, uint32_t address, uint64_t value) {
|
void TraceMemoryStoreI64(void* raw_context, uint32_t address, uint64_t value) {
|
||||||
auto thread_state = *reinterpret_cast<ThreadState**>(raw_context);
|
auto ppc_context = reinterpret_cast<ppc::PPCContext*>(raw_context);
|
||||||
DPRINT("store.i64 {:08X} = {} ({:X})\n", address, (int64_t)value, value);
|
DPRINT("store.i64 {:08X} = {} ({:X})\n", address, (int64_t)value, value);
|
||||||
}
|
}
|
||||||
void TraceMemoryStoreF32(void* raw_context, uint32_t address, __m128 value) {
|
void TraceMemoryStoreF32(void* raw_context, uint32_t address, __m128 value) {
|
||||||
auto thread_state = *reinterpret_cast<ThreadState**>(raw_context);
|
auto ppc_context = reinterpret_cast<ppc::PPCContext*>(raw_context);
|
||||||
DPRINT("store.f32 {:08X} = {} ({:X})\n", address, xe::m128_f32<0>(value),
|
DPRINT("store.f32 {:08X} = {} ({:X})\n", address, xe::m128_f32<0>(value),
|
||||||
xe::m128_i32<0>(value));
|
xe::m128_i32<0>(value));
|
||||||
}
|
}
|
||||||
void TraceMemoryStoreF64(void* raw_context, uint32_t address, __m128 value) {
|
void TraceMemoryStoreF64(void* raw_context, uint32_t address, __m128 value) {
|
||||||
auto thread_state = *reinterpret_cast<ThreadState**>(raw_context);
|
auto ppc_context = reinterpret_cast<ppc::PPCContext*>(raw_context);
|
||||||
DPRINT("store.f64 {:08X} = {} ({:X})\n", address, xe::m128_f64<0>(value),
|
DPRINT("store.f64 {:08X} = {} ({:X})\n", address, xe::m128_f64<0>(value),
|
||||||
xe::m128_i64<0>(value));
|
xe::m128_i64<0>(value));
|
||||||
}
|
}
|
||||||
void TraceMemoryStoreV128(void* raw_context, uint32_t address, __m128 value) {
|
void TraceMemoryStoreV128(void* raw_context, uint32_t address, __m128 value) {
|
||||||
auto thread_state = *reinterpret_cast<ThreadState**>(raw_context);
|
auto ppc_context = reinterpret_cast<ppc::PPCContext*>(raw_context);
|
||||||
DPRINT(
|
DPRINT(
|
||||||
"store.v128 {:08X} = [{}, {}, {}, {}] [{:08X}, {:08X}, {:08X}, {:08X}]\n",
|
"store.v128 {:08X} = [{}, {}, {}, {}] [{:08X}, {:08X}, {:08X}, {:08X}]\n",
|
||||||
address, xe::m128_f32<0>(value), xe::m128_f32<1>(value),
|
address, xe::m128_f32<0>(value), xe::m128_f32<1>(value),
|
||||||
|
|
@ -202,7 +202,7 @@ void TraceMemoryStoreV128(void* raw_context, uint32_t address, __m128 value) {
|
||||||
|
|
||||||
void TraceMemset(void* raw_context, uint32_t address, uint8_t value,
|
void TraceMemset(void* raw_context, uint32_t address, uint8_t value,
|
||||||
uint32_t length) {
|
uint32_t length) {
|
||||||
auto thread_state = *reinterpret_cast<ThreadState**>(raw_context);
|
auto ppc_context = reinterpret_cast<ppc::PPCContext*>(raw_context);
|
||||||
DPRINT("memset {:08X}-{:08X} ({}) = {:02X}", address, address + length,
|
DPRINT("memset {:08X}-{:08X} ({}) = {:02X}", address, address + length,
|
||||||
length, value);
|
length, value);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ namespace kernel {
|
||||||
|
|
||||||
KernelModule::KernelModule(KernelState* kernel_state,
|
KernelModule::KernelModule(KernelState* kernel_state,
|
||||||
const std::string_view path)
|
const std::string_view path)
|
||||||
: XModule(kernel_state, ModuleType::kKernelModule) {
|
: XModule(kernel_state, ModuleType::kKernelModule, true) {
|
||||||
emulator_ = kernel_state->emulator();
|
emulator_ = kernel_state->emulator();
|
||||||
memory_ = emulator_->memory();
|
memory_ = emulator_->memory();
|
||||||
export_resolver_ = kernel_state->emulator()->export_resolver();
|
export_resolver_ = kernel_state->emulator()->export_resolver();
|
||||||
|
|
@ -29,9 +29,6 @@ KernelModule::KernelModule(KernelState* kernel_state,
|
||||||
path_ = path;
|
path_ = path;
|
||||||
name_ = utf8::find_base_name_from_guest_path(path);
|
name_ = utf8::find_base_name_from_guest_path(path);
|
||||||
|
|
||||||
// Persist this object through reloads.
|
|
||||||
host_object_ = true;
|
|
||||||
|
|
||||||
// HACK: Allocates memory where xboxkrnl.exe would be!
|
// HACK: Allocates memory where xboxkrnl.exe would be!
|
||||||
// TODO: Need to free this memory when necessary.
|
// TODO: Need to free this memory when necessary.
|
||||||
auto heap = memory()->LookupHeap(0x80040000);
|
auto heap = memory()->LookupHeap(0x80040000);
|
||||||
|
|
|
||||||
|
|
@ -35,26 +35,37 @@ void ObjectTable::Reset() {
|
||||||
entry.object->Release();
|
entry.object->Release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (uint32_t n = 0; n < host_table_capacity_; n++) {
|
||||||
table_capacity_ = 0;
|
ObjectTableEntry& entry = host_table_[n];
|
||||||
last_free_entry_ = 0;
|
if (entry.object) {
|
||||||
free(table_);
|
entry.object->Release();
|
||||||
table_ = nullptr;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
X_STATUS ObjectTable::FindFreeSlot(uint32_t* out_slot) {
|
table_capacity_ = 0;
|
||||||
|
host_table_capacity_ = 0;
|
||||||
|
last_free_entry_ = 0;
|
||||||
|
last_free_host_entry_ = 0;
|
||||||
|
free(table_);
|
||||||
|
table_ = nullptr;
|
||||||
|
free(host_table_);
|
||||||
|
host_table_ = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
X_STATUS ObjectTable::FindFreeSlot(uint32_t* out_slot, bool host) {
|
||||||
// Find a free slot.
|
// Find a free slot.
|
||||||
uint32_t slot = last_free_entry_;
|
uint32_t slot = host ? last_free_host_entry_ : last_free_entry_;
|
||||||
|
uint32_t capacity = host ? host_table_capacity_ : table_capacity_;
|
||||||
uint32_t scan_count = 0;
|
uint32_t scan_count = 0;
|
||||||
while (scan_count < table_capacity_) {
|
while (scan_count < capacity) {
|
||||||
ObjectTableEntry& entry = table_[slot];
|
ObjectTableEntry& entry = host ? host_table_[slot] : table_[slot];
|
||||||
if (!entry.object) {
|
if (!entry.object) {
|
||||||
*out_slot = slot;
|
*out_slot = slot;
|
||||||
return X_STATUS_SUCCESS;
|
return X_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
scan_count++;
|
scan_count++;
|
||||||
slot = (slot + 1) % table_capacity_;
|
slot = (slot + 1) % capacity;
|
||||||
if (slot == 0) {
|
if (slot == 0 && host) {
|
||||||
// Never allow 0 handles.
|
// Never allow 0 handles.
|
||||||
scan_count++;
|
scan_count++;
|
||||||
slot++;
|
slot++;
|
||||||
|
|
@ -62,23 +73,24 @@ X_STATUS ObjectTable::FindFreeSlot(uint32_t* out_slot) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Table out of slots, expand.
|
// Table out of slots, expand.
|
||||||
uint32_t new_table_capacity = std::max(16 * 1024u, table_capacity_ * 2);
|
uint32_t new_table_capacity = std::max(16 * 1024u, capacity * 2);
|
||||||
if (!Resize(new_table_capacity)) {
|
if (!Resize(new_table_capacity, host)) {
|
||||||
return X_STATUS_NO_MEMORY;
|
return X_STATUS_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Never allow 0 handles.
|
// Never allow 0 handles on host.
|
||||||
slot = ++last_free_entry_;
|
slot = host ? ++last_free_host_entry_ : last_free_entry_++;
|
||||||
*out_slot = slot;
|
*out_slot = slot;
|
||||||
|
|
||||||
return X_STATUS_SUCCESS;
|
return X_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ObjectTable::Resize(uint32_t new_capacity) {
|
bool ObjectTable::Resize(uint32_t new_capacity, bool host) {
|
||||||
|
uint32_t capacity = host ? host_table_capacity_ : table_capacity_;
|
||||||
uint32_t new_size = new_capacity * sizeof(ObjectTableEntry);
|
uint32_t new_size = new_capacity * sizeof(ObjectTableEntry);
|
||||||
uint32_t old_size = table_capacity_ * sizeof(ObjectTableEntry);
|
uint32_t old_size = capacity * sizeof(ObjectTableEntry);
|
||||||
auto new_table =
|
auto new_table = reinterpret_cast<ObjectTableEntry*>(
|
||||||
reinterpret_cast<ObjectTableEntry*>(realloc(table_, new_size));
|
realloc(host ? host_table_ : table_, new_size));
|
||||||
if (!new_table) {
|
if (!new_table) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -89,9 +101,15 @@ bool ObjectTable::Resize(uint32_t new_capacity) {
|
||||||
new_size - old_size);
|
new_size - old_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
last_free_entry_ = table_capacity_;
|
if (host) {
|
||||||
|
last_free_host_entry_ = capacity;
|
||||||
|
host_table_capacity_ = new_capacity;
|
||||||
|
host_table_ = new_table;
|
||||||
|
} else {
|
||||||
|
last_free_entry_ = capacity;
|
||||||
table_capacity_ = new_capacity;
|
table_capacity_ = new_capacity;
|
||||||
table_ = new_table;
|
table_ = new_table;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -105,14 +123,16 @@ X_STATUS ObjectTable::AddHandle(XObject* object, X_HANDLE* out_handle) {
|
||||||
|
|
||||||
// Find a free slot.
|
// Find a free slot.
|
||||||
uint32_t slot = 0;
|
uint32_t slot = 0;
|
||||||
result = FindFreeSlot(&slot);
|
bool host_object = object->is_host_object();
|
||||||
|
result = FindFreeSlot(&slot, host_object);
|
||||||
|
|
||||||
// Stash.
|
// Stash.
|
||||||
if (XSUCCEEDED(result)) {
|
if (XSUCCEEDED(result)) {
|
||||||
ObjectTableEntry& entry = table_[slot];
|
ObjectTableEntry& entry = host_object ? host_table_[slot] : table_[slot];
|
||||||
entry.object = object;
|
entry.object = object;
|
||||||
entry.handle_ref_count = 1;
|
entry.handle_ref_count = 1;
|
||||||
handle = XObject::kHandleBase + (slot << 2);
|
handle = slot << 2;
|
||||||
|
if (!host_object) handle += XObject::kHandleBase;
|
||||||
object->handles().push_back(handle);
|
object->handles().push_back(handle);
|
||||||
|
|
||||||
// Retain so long as the object is in the table.
|
// Retain so long as the object is in the table.
|
||||||
|
|
@ -222,6 +242,14 @@ std::vector<object_ref<XObject>> ObjectTable::GetAllObjects() {
|
||||||
auto lock = global_critical_region_.Acquire();
|
auto lock = global_critical_region_.Acquire();
|
||||||
std::vector<object_ref<XObject>> results;
|
std::vector<object_ref<XObject>> results;
|
||||||
|
|
||||||
|
for (uint32_t slot = 0; slot < host_table_capacity_; slot++) {
|
||||||
|
auto& entry = host_table_[slot];
|
||||||
|
if (entry.object && std::find(results.begin(), results.end(),
|
||||||
|
entry.object) == results.end()) {
|
||||||
|
entry.object->Retain();
|
||||||
|
results.push_back(object_ref<XObject>(entry.object));
|
||||||
|
}
|
||||||
|
}
|
||||||
for (uint32_t slot = 0; slot < table_capacity_; slot++) {
|
for (uint32_t slot = 0; slot < table_capacity_; slot++) {
|
||||||
auto& entry = table_[slot];
|
auto& entry = table_[slot];
|
||||||
if (entry.object && std::find(results.begin(), results.end(),
|
if (entry.object && std::find(results.begin(), results.end(),
|
||||||
|
|
@ -238,7 +266,7 @@ void ObjectTable::PurgeAllObjects() {
|
||||||
auto lock = global_critical_region_.Acquire();
|
auto lock = global_critical_region_.Acquire();
|
||||||
for (uint32_t slot = 0; slot < table_capacity_; slot++) {
|
for (uint32_t slot = 0; slot < table_capacity_; slot++) {
|
||||||
auto& entry = table_[slot];
|
auto& entry = table_[slot];
|
||||||
if (entry.object && !entry.object->is_host_object()) {
|
if (entry.object) {
|
||||||
entry.handle_ref_count = 0;
|
entry.handle_ref_count = 0;
|
||||||
entry.object->Release();
|
entry.object->Release();
|
||||||
|
|
||||||
|
|
@ -259,8 +287,13 @@ ObjectTable::ObjectTableEntry* ObjectTable::LookupTableInLock(X_HANDLE handle) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lower 2 bits are ignored.
|
// Lower 2 bits are ignored.
|
||||||
uint32_t slot = GetHandleSlot(handle);
|
bool host = (handle < XObject::kHandleBase);
|
||||||
if (slot <= table_capacity_) {
|
uint32_t slot = GetHandleSlot(handle, host);
|
||||||
|
if (host) {
|
||||||
|
if (slot <= host_table_capacity_) {
|
||||||
|
return &host_table_[slot];
|
||||||
|
}
|
||||||
|
} else if (slot <= table_capacity_) {
|
||||||
return &table_[slot];
|
return &table_[slot];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -288,10 +321,18 @@ XObject* ObjectTable::LookupObject(X_HANDLE handle, bool already_locked) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lower 2 bits are ignored.
|
// Lower 2 bits are ignored.
|
||||||
uint32_t slot = GetHandleSlot(handle);
|
bool host = (handle < XObject::kHandleBase);
|
||||||
|
uint32_t slot = GetHandleSlot(handle, host);
|
||||||
|
|
||||||
// Verify slot.
|
// Verify slot.
|
||||||
if (slot < table_capacity_) {
|
if (host) {
|
||||||
|
if (slot < host_table_capacity_) {
|
||||||
|
ObjectTableEntry& entry = host_table_[slot];
|
||||||
|
if (entry.object) {
|
||||||
|
object = entry.object;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (slot < table_capacity_) {
|
||||||
ObjectTableEntry& entry = table_[slot];
|
ObjectTableEntry& entry = table_[slot];
|
||||||
if (entry.object) {
|
if (entry.object) {
|
||||||
object = entry.object;
|
object = entry.object;
|
||||||
|
|
@ -313,6 +354,15 @@ XObject* ObjectTable::LookupObject(X_HANDLE handle, bool already_locked) {
|
||||||
void ObjectTable::GetObjectsByType(XObject::Type type,
|
void ObjectTable::GetObjectsByType(XObject::Type type,
|
||||||
std::vector<object_ref<XObject>>* results) {
|
std::vector<object_ref<XObject>>* results) {
|
||||||
auto global_lock = global_critical_region_.Acquire();
|
auto global_lock = global_critical_region_.Acquire();
|
||||||
|
for (uint32_t slot = 0; slot < host_table_capacity_; ++slot) {
|
||||||
|
auto& entry = host_table_[slot];
|
||||||
|
if (entry.object) {
|
||||||
|
if (entry.object->type() == type) {
|
||||||
|
entry.object->Retain();
|
||||||
|
results->push_back(object_ref<XObject>(entry.object));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
for (uint32_t slot = 0; slot < table_capacity_; ++slot) {
|
for (uint32_t slot = 0; slot < table_capacity_; ++slot) {
|
||||||
auto& entry = table_[slot];
|
auto& entry = table_[slot];
|
||||||
if (entry.object) {
|
if (entry.object) {
|
||||||
|
|
@ -377,6 +427,12 @@ X_STATUS ObjectTable::GetObjectByName(const std::string_view name,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ObjectTable::Save(ByteStream* stream) {
|
bool ObjectTable::Save(ByteStream* stream) {
|
||||||
|
stream->Write<uint32_t>(host_table_capacity_);
|
||||||
|
for (uint32_t i = 0; i < host_table_capacity_; i++) {
|
||||||
|
auto& entry = host_table_[i];
|
||||||
|
stream->Write<int32_t>(entry.handle_ref_count);
|
||||||
|
}
|
||||||
|
|
||||||
stream->Write<uint32_t>(table_capacity_);
|
stream->Write<uint32_t>(table_capacity_);
|
||||||
for (uint32_t i = 0; i < table_capacity_; i++) {
|
for (uint32_t i = 0; i < table_capacity_; i++) {
|
||||||
auto& entry = table_[i];
|
auto& entry = table_[i];
|
||||||
|
|
@ -387,7 +443,14 @@ bool ObjectTable::Save(ByteStream* stream) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ObjectTable::Restore(ByteStream* stream) {
|
bool ObjectTable::Restore(ByteStream* stream) {
|
||||||
Resize(stream->Read<uint32_t>());
|
Resize(stream->Read<uint32_t>(), true);
|
||||||
|
for (uint32_t i = 0; i < host_table_capacity_; i++) {
|
||||||
|
auto& entry = host_table_[i];
|
||||||
|
// entry.object = nullptr;
|
||||||
|
entry.handle_ref_count = stream->Read<int32_t>();
|
||||||
|
}
|
||||||
|
|
||||||
|
Resize(stream->Read<uint32_t>(), false);
|
||||||
for (uint32_t i = 0; i < table_capacity_; i++) {
|
for (uint32_t i = 0; i < table_capacity_; i++) {
|
||||||
auto& entry = table_[i];
|
auto& entry = table_[i];
|
||||||
// entry.object = nullptr;
|
// entry.object = nullptr;
|
||||||
|
|
@ -398,11 +461,13 @@ bool ObjectTable::Restore(ByteStream* stream) {
|
||||||
}
|
}
|
||||||
|
|
||||||
X_STATUS ObjectTable::RestoreHandle(X_HANDLE handle, XObject* object) {
|
X_STATUS ObjectTable::RestoreHandle(X_HANDLE handle, XObject* object) {
|
||||||
uint32_t slot = GetHandleSlot(handle);
|
bool host = (handle < XObject::kHandleBase);
|
||||||
assert_true(table_capacity_ >= slot);
|
uint32_t slot = GetHandleSlot(handle, host);
|
||||||
|
uint32_t capacity = host ? host_table_capacity_ : table_capacity_;
|
||||||
|
assert_true(capacity >= slot);
|
||||||
|
|
||||||
if (table_capacity_ >= slot) {
|
if (capacity >= slot) {
|
||||||
auto& entry = table_[slot];
|
auto& entry = host ? host_table_[slot] : table_[slot];
|
||||||
entry.object = object;
|
entry.object = object;
|
||||||
object->Retain();
|
object->Retain();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -49,10 +49,10 @@ class ObjectTable {
|
||||||
X_STATUS RestoreHandle(X_HANDLE handle, XObject* object);
|
X_STATUS RestoreHandle(X_HANDLE handle, XObject* object);
|
||||||
template <typename T>
|
template <typename T>
|
||||||
object_ref<T> LookupObject(X_HANDLE handle, bool already_locked = false) {
|
object_ref<T> LookupObject(X_HANDLE handle, bool already_locked = false) {
|
||||||
auto object = LookupObject(handle, already_locked);
|
|
||||||
if (T::kObjectType == XObject::Type::Socket) {
|
if (T::kObjectType == XObject::Type::Socket) {
|
||||||
object = LookupObject((handle | 0xF8000000), false);
|
handle |= XObject::kHandleBase;
|
||||||
}
|
}
|
||||||
|
auto object = LookupObject(handle, already_locked);
|
||||||
if (object) {
|
if (object) {
|
||||||
assert_true(object->type() == T::kObjectType);
|
assert_true(object->type() == T::kObjectType);
|
||||||
}
|
}
|
||||||
|
|
@ -95,16 +95,20 @@ class ObjectTable {
|
||||||
std::vector<object_ref<XObject>>* results);
|
std::vector<object_ref<XObject>>* results);
|
||||||
|
|
||||||
X_HANDLE TranslateHandle(X_HANDLE handle);
|
X_HANDLE TranslateHandle(X_HANDLE handle);
|
||||||
static constexpr uint32_t GetHandleSlot(X_HANDLE handle) {
|
static constexpr uint32_t GetHandleSlot(X_HANDLE handle, bool host) {
|
||||||
return (handle - XObject::kHandleBase) >> 2;
|
if (!host) handle -= XObject::kHandleBase;
|
||||||
|
return handle >> 2;
|
||||||
}
|
}
|
||||||
X_STATUS FindFreeSlot(uint32_t* out_slot);
|
X_STATUS FindFreeSlot(uint32_t* out_slot, bool host);
|
||||||
bool Resize(uint32_t new_capacity);
|
bool Resize(uint32_t new_capacity, bool host);
|
||||||
|
|
||||||
xe::global_critical_region global_critical_region_;
|
xe::global_critical_region global_critical_region_;
|
||||||
uint32_t table_capacity_ = 0;
|
uint32_t table_capacity_ = 0;
|
||||||
|
uint32_t host_table_capacity_ = 0;
|
||||||
ObjectTableEntry* table_ = nullptr;
|
ObjectTableEntry* table_ = nullptr;
|
||||||
|
ObjectTableEntry* host_table_ = nullptr;
|
||||||
uint32_t last_free_entry_ = 0;
|
uint32_t last_free_entry_ = 0;
|
||||||
|
uint32_t last_free_host_entry_ = 0;
|
||||||
std::unordered_map<string_key_case, X_HANDLE> name_table_;
|
std::unordered_map<string_key_case, X_HANDLE> name_table_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@
|
||||||
#include "third_party/fmt/include/fmt/format.h"
|
#include "third_party/fmt/include/fmt/format.h"
|
||||||
|
|
||||||
DEFINE_int32(avpack, 8, "Video modes", "Video");
|
DEFINE_int32(avpack, 8, "Video modes", "Video");
|
||||||
|
DECLARE_int32(user_country);
|
||||||
DECLARE_int32(user_language);
|
DECLARE_int32(user_language);
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
|
|
@ -206,7 +207,25 @@ dword_result_t XGetAVPack_entry() {
|
||||||
}
|
}
|
||||||
DECLARE_XAM_EXPORT1(XGetAVPack, kNone, kStub);
|
DECLARE_XAM_EXPORT1(XGetAVPack, kNone, kStub);
|
||||||
|
|
||||||
uint32_t xeXGetGameRegion() { return 0xFFFFu; }
|
uint32_t xeXGetGameRegion() {
|
||||||
|
static uint32_t const table[] = {
|
||||||
|
0xFFFFu, 0x03FFu, 0x02FEu, 0x02FEu, 0x03FFu, 0x02FEu, 0x0201u, 0x03FFu,
|
||||||
|
0x02FEu, 0x02FEu, 0x03FFu, 0x03FFu, 0x03FFu, 0x03FFu, 0x02FEu, 0x03FFu,
|
||||||
|
0x00FFu, 0xFFFFu, 0x02FEu, 0x03FFu, 0x0102u, 0x03FFu, 0x03FFu, 0x02FEu,
|
||||||
|
0x02FEu, 0x02FEu, 0x03FFu, 0x03FFu, 0x03FFu, 0x02FEu, 0x03FFu, 0x02FEu,
|
||||||
|
0x02FEu, 0x02FEu, 0x02FEu, 0x02FEu, 0x02FEu, 0x02FEu, 0x03FFu, 0x03FFu,
|
||||||
|
0x03FFu, 0x02FEu, 0x02FEu, 0x03FFu, 0x02FEu, 0x02FEu, 0x03FFu, 0x03FFu,
|
||||||
|
0x03FFu, 0x02FEu, 0x02FEu, 0x03FFu, 0x03FFu, 0x0101u, 0x03FFu, 0x03FFu,
|
||||||
|
0x03FFu, 0x03FFu, 0x03FFu, 0x03FFu, 0x02FEu, 0x02FEu, 0x02FEu, 0x02FEu,
|
||||||
|
0x03FFu, 0x03FFu, 0x02FEu, 0x02FEu, 0x03FFu, 0x0102u, 0x03FFu, 0x00FFu,
|
||||||
|
0x03FFu, 0x03FFu, 0x02FEu, 0x02FEu, 0x0201u, 0x03FFu, 0x03FFu, 0x03FFu,
|
||||||
|
0x03FFu, 0x03FFu, 0x02FEu, 0x03FFu, 0x02FEu, 0x03FFu, 0x03FFu, 0x02FEu,
|
||||||
|
0x02FEu, 0x03FFu, 0x02FEu, 0x03FFu, 0x02FEu, 0x02FEu, 0xFFFFu, 0x03FFu,
|
||||||
|
0x03FFu, 0x03FFu, 0x03FFu, 0x02FEu, 0x03FFu, 0x03FFu, 0x02FEu, 0x00FFu,
|
||||||
|
0x03FFu, 0x03FFu, 0x03FFu, 0x03FFu, 0x03FFu, 0x03FFu, 0x03FFu};
|
||||||
|
auto country = static_cast<uint8_t>(cvars::user_country);
|
||||||
|
return country < xe::countof(table) ? table[country] : 0xFFFFu;
|
||||||
|
}
|
||||||
|
|
||||||
dword_result_t XGetGameRegion_entry() { return xeXGetGameRegion(); }
|
dword_result_t XGetGameRegion_entry() { return xeXGetGameRegion(); }
|
||||||
DECLARE_XAM_EXPORT1(XGetGameRegion, kNone, kStub);
|
DECLARE_XAM_EXPORT1(XGetGameRegion, kNone, kStub);
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,9 @@
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace kernel {
|
namespace kernel {
|
||||||
|
|
||||||
XModule::XModule(KernelState* kernel_state, ModuleType module_type)
|
XModule::XModule(KernelState* kernel_state, ModuleType module_type,
|
||||||
: XObject(kernel_state, kObjectType),
|
bool host_object)
|
||||||
|
: XObject(kernel_state, kObjectType, host_object),
|
||||||
module_type_(module_type),
|
module_type_(module_type),
|
||||||
processor_module_(nullptr),
|
processor_module_(nullptr),
|
||||||
hmodule_ptr_(0) {
|
hmodule_ptr_(0) {
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,8 @@ class XModule : public XObject {
|
||||||
|
|
||||||
static const XObject::Type kObjectType = XObject::Type::Module;
|
static const XObject::Type kObjectType = XObject::Type::Module;
|
||||||
|
|
||||||
XModule(KernelState* kernel_state, ModuleType module_type);
|
XModule(KernelState* kernel_state, ModuleType module_type,
|
||||||
|
bool host_object = false);
|
||||||
virtual ~XModule();
|
virtual ~XModule();
|
||||||
|
|
||||||
ModuleType module_type() const { return module_type_; }
|
ModuleType module_type() const { return module_type_; }
|
||||||
|
|
|
||||||
|
|
@ -34,12 +34,13 @@ XObject::XObject(Type type)
|
||||||
handles_.reserve(10);
|
handles_.reserve(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
XObject::XObject(KernelState* kernel_state, Type type)
|
XObject::XObject(KernelState* kernel_state, Type type, bool host_object)
|
||||||
: kernel_state_(kernel_state),
|
: kernel_state_(kernel_state),
|
||||||
type_(type),
|
type_(type),
|
||||||
pointer_ref_count_(1),
|
pointer_ref_count_(1),
|
||||||
guest_object_ptr_(0),
|
guest_object_ptr_(0),
|
||||||
allocated_guest_object_(false) {
|
allocated_guest_object_(false),
|
||||||
|
host_object_(host_object) {
|
||||||
handles_.reserve(10);
|
handles_.reserve(10);
|
||||||
|
|
||||||
// TODO: Assert kernel_state != nullptr in this constructor.
|
// TODO: Assert kernel_state != nullptr in this constructor.
|
||||||
|
|
|
||||||
|
|
@ -136,7 +136,7 @@ class XObject {
|
||||||
};
|
};
|
||||||
|
|
||||||
XObject(Type type);
|
XObject(Type type);
|
||||||
XObject(KernelState* kernel_state, Type type);
|
XObject(KernelState* kernel_state, Type type, bool host_object = false);
|
||||||
virtual ~XObject();
|
virtual ~XObject();
|
||||||
|
|
||||||
Emulator* emulator() const;
|
Emulator* emulator() const;
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ XThread::XThread(KernelState* kernel_state, uint32_t stack_size,
|
||||||
uint32_t xapi_thread_startup, uint32_t start_address,
|
uint32_t xapi_thread_startup, uint32_t start_address,
|
||||||
uint32_t start_context, uint32_t creation_flags,
|
uint32_t start_context, uint32_t creation_flags,
|
||||||
bool guest_thread, bool main_thread)
|
bool guest_thread, bool main_thread)
|
||||||
: XObject(kernel_state, kObjectType),
|
: XObject(kernel_state, kObjectType, !guest_thread),
|
||||||
thread_id_(++next_xthread_id_),
|
thread_id_(++next_xthread_id_),
|
||||||
guest_thread_(guest_thread),
|
guest_thread_(guest_thread),
|
||||||
main_thread_(main_thread),
|
main_thread_(main_thread),
|
||||||
|
|
@ -79,10 +79,6 @@ XThread::XThread(KernelState* kernel_state, uint32_t stack_size,
|
||||||
creation_params_.stack_size = 16 * 1024;
|
creation_params_.stack_size = 16 * 1024;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!guest_thread_) {
|
|
||||||
host_object_ = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The kernel does not take a reference. We must unregister in the dtor.
|
// The kernel does not take a reference. We must unregister in the dtor.
|
||||||
kernel_state_->RegisterThread(this);
|
kernel_state_->RegisterThread(this);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue