diff --git a/kernel/include/kernel/Scheduler.h b/kernel/include/kernel/Scheduler.h index 6785b536f7..a791a0a454 100644 --- a/kernel/include/kernel/Scheduler.h +++ b/kernel/include/kernel/Scheduler.h @@ -82,6 +82,8 @@ namespace Kernel void timer_interrupt(); + static BAN::ErrorOr bind_thread_to_processor(Thread*, ProcessorID); + // if thread is already bound, this will never fail BAN::ErrorOr add_thread(Thread*); void block_current_thread(ThreadBlocker* thread_blocker, uint64_t wake_time_ns); diff --git a/kernel/kernel/Scheduler.cpp b/kernel/kernel/Scheduler.cpp index c0706929da..69fa10d63c 100644 --- a/kernel/kernel/Scheduler.cpp +++ b/kernel/kernel/Scheduler.cpp @@ -567,25 +567,37 @@ namespace Kernel } #endif - BAN::ErrorOr Scheduler::add_thread(Thread* thread) + BAN::ErrorOr Scheduler::bind_thread_to_processor(Thread* thread, ProcessorID processor_id) { + ASSERT(thread->m_scheduler_node == nullptr); auto* new_node = new SchedulerQueue::Node(thread); if (new_node == nullptr) return BAN::Error::from_errno(ENOMEM); - const size_t processor_index = s_next_processor_index++ % Processor::count(); - const auto processor_id = Processor::id_from_index(processor_index); - + ASSERT(processor_id != PROCESSOR_NONE); new_node->processor_id = processor_id; thread->m_scheduler_node = new_node; - if (processor_id == Processor::current_id()) - add_thread(new_node); + return {}; + } + + BAN::ErrorOr Scheduler::add_thread(Thread* thread) + { + if (thread->m_scheduler_node == nullptr) + { + const size_t processor_index = s_next_processor_index++ % Processor::count(); + const auto processor_id = Processor::id_from_index(processor_index); + TRY(bind_thread_to_processor(thread, processor_id)); + } + + auto* node = thread->m_scheduler_node; + if (node->processor_id == Processor::current_id()) + add_thread(node); else { - Processor::send_smp_message(processor_id, { + Processor::send_smp_message(node->processor_id, { .type = Processor::SMPMessage::Type::NewThread, - .new_thread = new_node + .new_thread = node }); }