Allocating stacks in the right place.

This commit is contained in:
Ben Vanik 2015-05-17 13:10:02 -07:00
parent 37804d692c
commit b44a7a7730
6 changed files with 39 additions and 14 deletions

View File

@ -90,7 +90,9 @@ X_STATUS AudioSystem::Setup() {
registers_.next_context = 1;
// Setup worker thread state. This lets us make calls into guest code.
thread_state_ = new ThreadState(emulator_->processor(), 0, 0, 128 * 1024, 0);
thread_state_ =
new ThreadState(emulator_->processor(), 0, ThreadStackType::kKernelStack,
0, 128 * 1024, 0);
thread_state_->set_name("Audio Worker");
thread_block_ = memory()->SystemHeapAlloc(2048);
thread_state_->context()->r[13] = thread_block_;

View File

@ -148,7 +148,8 @@ bool Processor::Setup() {
backend_ = std::move(backend);
frontend_ = std::move(frontend);
interrupt_thread_state_ = new ThreadState(this, 0, 0, 128 * 1024, 0);
interrupt_thread_state_ =
new ThreadState(this, 0, ThreadStackType::kKernelStack, 0, 128 * 1024, 0);
interrupt_thread_state_->set_name("Interrupt");
interrupt_thread_block_ = memory_->SystemHeapAlloc(2048);
interrupt_thread_state_->context()->r[13] = interrupt_thread_block_;

View File

@ -70,8 +70,8 @@ class TestFunction {
uint32_t stack_size = 64 * 1024;
uint32_t stack_address = memory_size - stack_size;
uint32_t thread_state_address = stack_address - 0x1000;
auto thread_state =
std::make_unique<ThreadState>(processor.get(), 0x100, stack_address,
auto thread_state = std::make_unique<ThreadState>(
processor.get(), 0x100, ThreadStackType::kUserStack, stack_address,
stack_size, thread_state_address);
auto ctx = thread_state->context();
ctx->lr = 0xBEBEBEBE;

View File

@ -27,11 +27,12 @@ using PPCContext = xe::cpu::frontend::PPCContext;
thread_local ThreadState* thread_state_ = nullptr;
ThreadState::ThreadState(Processor* processor, uint32_t thread_id,
uint32_t stack_address, uint32_t stack_size,
uint32_t pcr_address)
ThreadStackType stack_type, uint32_t stack_address,
uint32_t stack_size, uint32_t pcr_address)
: processor_(processor),
memory_(processor->memory()),
thread_id_(thread_id),
stack_type_(stack_type),
name_(""),
backend_data_(0),
stack_size_(stack_size),
@ -49,11 +50,23 @@ ThreadState::ThreadState(Processor* processor, uint32_t thread_id,
uint32_t stack_alignment = (stack_size & 0xF000) ? 0x1000 : 0x10000;
uint32_t stack_padding = stack_alignment * 1;
uint32_t actual_stack_size = stack_padding + stack_size;
bool top_down;
switch (stack_type) {
case ThreadStackType::kKernelStack:
top_down = true;
break;
case ThreadStackType::kUserStack:
top_down = false;
break;
default:
assert_unhandled_case(stack_type);
break;
}
memory()
->LookupHeapByType(false, stack_alignment)
->Alloc(actual_stack_size, stack_alignment,
->LookupHeap(0x70000000)
->AllocRange(0x70000000, 0x7FFFFFFF, actual_stack_size, stack_alignment,
kMemoryAllocationReserve | kMemoryAllocationCommit,
kMemoryProtectRead | kMemoryProtectWrite, true,
kMemoryProtectRead | kMemoryProtectWrite, top_down,
&stack_address_);
assert_true(!(stack_address_ & 0xFFF)); // just to be safe
stack_allocated_ = true;

View File

@ -19,15 +19,22 @@ namespace cpu {
class Processor;
enum class ThreadStackType {
kKernelStack,
kUserStack,
};
class ThreadState {
public:
ThreadState(Processor* processor, uint32_t thread_id, uint32_t stack_address,
ThreadState(Processor* processor, uint32_t thread_id,
ThreadStackType stack_type, uint32_t stack_address,
uint32_t stack_size, uint32_t pcr_address);
~ThreadState();
Processor* processor() const { return processor_; }
Memory* memory() const { return memory_; }
uint32_t thread_id() const { return thread_id_; }
ThreadStackType stack_type() const { return stack_type_; }
const std::string& name() const { return name_; }
void set_name(const std::string& value) { name_ = value; }
void* backend_data() const { return backend_data_; }
@ -50,6 +57,7 @@ class ThreadState {
Processor* processor_;
Memory* memory_;
uint32_t thread_id_;
ThreadStackType stack_type_;
std::string name_;
void* backend_data_;
uint32_t stack_address_;

View File

@ -171,7 +171,8 @@ X_STATUS XThread::Create() {
// Allocate processor thread state.
// This is thread safe.
thread_state_ = new ThreadState(kernel_state()->processor(), thread_id_, 0,
thread_state_ = new ThreadState(kernel_state()->processor(), thread_id_,
ThreadStackType::kUserStack, 0,
creation_params_.stack_size, pcr_address_);
XELOGI("XThread%04X (%X) Stack: %.8X-%.8X", handle(),
thread_state_->thread_id(), thread_state_->stack_limit(),