diff options
Diffstat (limited to 'src/core/hle/kernel/thread.cpp')
| -rw-r--r-- | src/core/hle/kernel/thread.cpp | 53 |
1 files changed, 52 insertions, 1 deletions
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 0a5441684..c370776e8 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp | |||
| @@ -273,7 +273,7 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point, | |||
| 273 | thread->name = std::move(name); | 273 | thread->name = std::move(name); |
| 274 | thread->callback_handle = wakeup_callback_handle_table.Create(thread).Unwrap(); | 274 | thread->callback_handle = wakeup_callback_handle_table.Create(thread).Unwrap(); |
| 275 | thread->owner_process = owner_process; | 275 | thread->owner_process = owner_process; |
| 276 | thread->scheduler = Core::System().GetInstance().Scheduler(static_cast<size_t>(processor_id)); | 276 | thread->scheduler = Core::System().GetInstance().Scheduler(processor_id); |
| 277 | thread->scheduler->AddThread(thread, priority); | 277 | thread->scheduler->AddThread(thread, priority); |
| 278 | 278 | ||
| 279 | // Find the next available TLS index, and mark it as used | 279 | // Find the next available TLS index, and mark it as used |
| @@ -415,6 +415,57 @@ void Thread::UpdatePriority() { | |||
| 415 | lock_owner->UpdatePriority(); | 415 | lock_owner->UpdatePriority(); |
| 416 | } | 416 | } |
| 417 | 417 | ||
| 418 | static s32 GetNextProcessorId(u64 mask) { | ||
| 419 | s32 processor_id{}; | ||
| 420 | for (s32 index = 0; index < Core::NUM_CPU_CORES; ++index) { | ||
| 421 | if (mask & (1ULL << index)) { | ||
| 422 | if (!Core::System().GetInstance().Scheduler(index)->GetCurrentThread()) { | ||
| 423 | // Core is enabled and not running any threads, use this one | ||
| 424 | return index; | ||
| 425 | } | ||
| 426 | |||
| 427 | // Core is enabled, but running a thread, less ideal | ||
| 428 | processor_id = index; | ||
| 429 | } | ||
| 430 | } | ||
| 431 | |||
| 432 | return processor_id; | ||
| 433 | } | ||
| 434 | |||
| 435 | void Thread::ChangeCore(u32 core, u64 mask) { | ||
| 436 | const s32 new_processor_id{GetNextProcessorId(mask)}; | ||
| 437 | |||
| 438 | ASSERT(ideal_core == core); // We're not doing anything with this yet, so assert the expected | ||
| 439 | ASSERT(new_processor_id < Core::NUM_CPU_CORES); | ||
| 440 | |||
| 441 | if (new_processor_id == processor_id) { | ||
| 442 | // Already running on ideal core, nothing to do here | ||
| 443 | return; | ||
| 444 | } | ||
| 445 | |||
| 446 | ASSERT(status != THREADSTATUS_RUNNING); // Unsupported | ||
| 447 | |||
| 448 | processor_id = new_processor_id; | ||
| 449 | ideal_core = core; | ||
| 450 | mask = mask; | ||
| 451 | |||
| 452 | // Add thread to new core's scheduler | ||
| 453 | auto& next_scheduler = Core::System().GetInstance().Scheduler(new_processor_id); | ||
| 454 | next_scheduler->AddThread(this, current_priority); | ||
| 455 | |||
| 456 | if (status == THREADSTATUS_READY) { | ||
| 457 | // If the thread was ready, unschedule from the previous core and schedule on the new core | ||
| 458 | scheduler->UnscheduleThread(this, current_priority); | ||
| 459 | next_scheduler->ScheduleThread(this, current_priority); | ||
| 460 | } | ||
| 461 | |||
| 462 | // Remove thread from previous core's scheduler | ||
| 463 | scheduler->RemoveThread(this); | ||
| 464 | |||
| 465 | // Change thread's scheduler | ||
| 466 | scheduler = next_scheduler; | ||
| 467 | } | ||
| 468 | |||
| 418 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 469 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
| 419 | 470 | ||
| 420 | /** | 471 | /** |