Core timing 2.0 (#4913)
* Core::Timing: Add multiple timer, one for each core * revert clang-format; work on tests for CoreTiming * Kernel:: Add support for multiple cores, asserts in HandleSyncRequest because Thread->status == WaitIPC * Add some TRACE_LOGs * fix tests * make some adjustments to qt-debugger, cheats and gdbstub(probably still broken) * Make ARM_Interface::id private, rework ARM_Interface ctor * ReRename TimingManager to Timing for smaler diff * addressed review comments
This commit is contained in:
parent
e3dbdcbdff
commit
55ec7031cc
32 changed files with 760 additions and 535 deletions
|
@ -33,13 +33,9 @@ void Thread::Acquire(Thread* thread) {
|
|||
ASSERT_MSG(!ShouldWait(thread), "object unavailable!");
|
||||
}
|
||||
|
||||
u32 ThreadManager::NewThreadId() {
|
||||
return next_thread_id++;
|
||||
}
|
||||
|
||||
Thread::Thread(KernelSystem& kernel)
|
||||
: WaitObject(kernel), context(kernel.GetThreadManager().NewContext()),
|
||||
thread_manager(kernel.GetThreadManager()) {}
|
||||
Thread::Thread(KernelSystem& kernel, u32 core_id)
|
||||
: WaitObject(kernel), context(kernel.GetThreadManager(core_id).NewContext()),
|
||||
thread_manager(kernel.GetThreadManager(core_id)) {}
|
||||
Thread::~Thread() {}
|
||||
|
||||
Thread* ThreadManager::GetCurrentThread() const {
|
||||
|
@ -84,7 +80,7 @@ void ThreadManager::SwitchContext(Thread* new_thread) {
|
|||
|
||||
// Save context for previous thread
|
||||
if (previous_thread) {
|
||||
previous_thread->last_running_ticks = timing.GetTicks();
|
||||
previous_thread->last_running_ticks = timing.GetGlobalTicks();
|
||||
cpu->SaveContext(previous_thread->context);
|
||||
|
||||
if (previous_thread->status == ThreadStatus::Running) {
|
||||
|
@ -111,7 +107,7 @@ void ThreadManager::SwitchContext(Thread* new_thread) {
|
|||
new_thread->status = ThreadStatus::Running;
|
||||
|
||||
if (previous_process.get() != current_thread->owner_process) {
|
||||
kernel.SetCurrentProcess(SharedFrom(current_thread->owner_process));
|
||||
kernel.SetCurrentProcessForCPU(SharedFrom(current_thread->owner_process), cpu->GetID());
|
||||
}
|
||||
|
||||
cpu->LoadContext(new_thread->context);
|
||||
|
@ -124,7 +120,7 @@ void ThreadManager::SwitchContext(Thread* new_thread) {
|
|||
}
|
||||
|
||||
Thread* ThreadManager::PopNextReadyThread() {
|
||||
Thread* next;
|
||||
Thread* next = nullptr;
|
||||
Thread* thread = GetCurrentThread();
|
||||
|
||||
if (thread && thread->status == ThreadStatus::Running) {
|
||||
|
@ -309,22 +305,22 @@ ResultVal<std::shared_ptr<Thread>> KernelSystem::CreateThread(std::string name,
|
|||
ErrorSummary::InvalidArgument, ErrorLevel::Permanent);
|
||||
}
|
||||
|
||||
auto thread{std::make_shared<Thread>(*this)};
|
||||
auto thread{std::make_shared<Thread>(*this, processor_id)};
|
||||
|
||||
thread_manager->thread_list.push_back(thread);
|
||||
thread_manager->ready_queue.prepare(priority);
|
||||
thread_managers[processor_id]->thread_list.push_back(thread);
|
||||
thread_managers[processor_id]->ready_queue.prepare(priority);
|
||||
|
||||
thread->thread_id = thread_manager->NewThreadId();
|
||||
thread->thread_id = NewThreadId();
|
||||
thread->status = ThreadStatus::Dormant;
|
||||
thread->entry_point = entry_point;
|
||||
thread->stack_top = stack_top;
|
||||
thread->nominal_priority = thread->current_priority = priority;
|
||||
thread->last_running_ticks = timing.GetTicks();
|
||||
thread->last_running_ticks = timing.GetGlobalTicks();
|
||||
thread->processor_id = processor_id;
|
||||
thread->wait_objects.clear();
|
||||
thread->wait_address = 0;
|
||||
thread->name = std::move(name);
|
||||
thread_manager->wakeup_callback_table[thread->thread_id] = thread.get();
|
||||
thread_managers[processor_id]->wakeup_callback_table[thread->thread_id] = thread.get();
|
||||
thread->owner_process = &owner_process;
|
||||
|
||||
// Find the next available TLS index, and mark it as used
|
||||
|
@ -369,7 +365,7 @@ ResultVal<std::shared_ptr<Thread>> KernelSystem::CreateThread(std::string name,
|
|||
// to initialize the context
|
||||
ResetThreadContext(thread->context, stack_top, entry_point, arg);
|
||||
|
||||
thread_manager->ready_queue.push_back(thread->current_priority, thread.get());
|
||||
thread_managers[processor_id]->ready_queue.push_back(thread->current_priority, thread.get());
|
||||
thread->status = ThreadStatus::Ready;
|
||||
|
||||
return MakeResult<std::shared_ptr<Thread>>(std::move(thread));
|
||||
|
@ -435,6 +431,9 @@ void ThreadManager::Reschedule() {
|
|||
LOG_TRACE(Kernel, "context switch {} -> idle", cur->GetObjectId());
|
||||
} else if (next) {
|
||||
LOG_TRACE(Kernel, "context switch idle -> {}", next->GetObjectId());
|
||||
} else {
|
||||
LOG_TRACE(Kernel, "context switch idle -> idle, do nothing");
|
||||
return;
|
||||
}
|
||||
|
||||
SwitchContext(next);
|
||||
|
@ -461,11 +460,10 @@ VAddr Thread::GetCommandBufferAddress() const {
|
|||
return GetTLSAddress() + command_header_offset;
|
||||
}
|
||||
|
||||
ThreadManager::ThreadManager(Kernel::KernelSystem& kernel) : kernel(kernel) {
|
||||
ThreadWakeupEventType =
|
||||
kernel.timing.RegisterEvent("ThreadWakeupCallback", [this](u64 thread_id, s64 cycle_late) {
|
||||
ThreadWakeupCallback(thread_id, cycle_late);
|
||||
});
|
||||
ThreadManager::ThreadManager(Kernel::KernelSystem& kernel, u32 core_id) : kernel(kernel) {
|
||||
ThreadWakeupEventType = kernel.timing.RegisterEvent(
|
||||
"ThreadWakeupCallback_" + std::to_string(core_id),
|
||||
[this](u64 thread_id, s64 cycle_late) { ThreadWakeupCallback(thread_id, cycle_late); });
|
||||
}
|
||||
|
||||
ThreadManager::~ThreadManager() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue