summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/svc.cpp
diff options
context:
space:
mode:
authorGravatar bunnei2018-05-02 22:36:51 -0400
committerGravatar bunnei2018-05-10 19:34:46 -0400
commita434fdcb102e96ddf564dc0973d7073d49bf19fc (patch)
treede758b0cc5ebcb67146397a74474fb898c0be51a /src/core/hle/kernel/svc.cpp
parentcore: Create a thread for each CPU core, keep in lock-step with a barrier. (diff)
downloadyuzu-a434fdcb102e96ddf564dc0973d7073d49bf19fc.tar.gz
yuzu-a434fdcb102e96ddf564dc0973d7073d49bf19fc.tar.xz
yuzu-a434fdcb102e96ddf564dc0973d7073d49bf19fc.zip
core: Implement multicore support.
Diffstat (limited to 'src/core/hle/kernel/svc.cpp')
-rw-r--r--src/core/hle/kernel/svc.cpp43
1 files changed, 22 insertions, 21 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 72b5c05f2..520510b61 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -485,22 +485,28 @@ static void ExitProcess() {
485 485
486 Core::CurrentProcess()->status = ProcessStatus::Exited; 486 Core::CurrentProcess()->status = ProcessStatus::Exited;
487 487
488 // Stop all the process threads that are currently waiting for objects. 488 auto stop_threads = [](const std::vector<SharedPtr<Thread>>& thread_list) {
489 auto& thread_list = Core::System::GetInstance().Scheduler().GetThreadList(); 489 for (auto& thread : thread_list) {
490 for (auto& thread : thread_list) { 490 if (thread->owner_process != Core::CurrentProcess())
491 if (thread->owner_process != Core::CurrentProcess()) 491 continue;
492 continue;
493 492
494 if (thread == GetCurrentThread()) 493 if (thread == GetCurrentThread())
495 continue; 494 continue;
496 495
497 // TODO(Subv): When are the other running/ready threads terminated? 496 // TODO(Subv): When are the other running/ready threads terminated?
498 ASSERT_MSG(thread->status == THREADSTATUS_WAIT_SYNCH_ANY || 497 ASSERT_MSG(thread->status == THREADSTATUS_WAIT_SYNCH_ANY ||
499 thread->status == THREADSTATUS_WAIT_SYNCH_ALL, 498 thread->status == THREADSTATUS_WAIT_SYNCH_ALL,
500 "Exiting processes with non-waiting threads is currently unimplemented"); 499 "Exiting processes with non-waiting threads is currently unimplemented");
501 500
502 thread->Stop(); 501 thread->Stop();
503 } 502 }
503 };
504
505 auto& system = Core::System::GetInstance();
506 stop_threads(system.Scheduler(0)->GetThreadList());
507 stop_threads(system.Scheduler(1)->GetThreadList());
508 stop_threads(system.Scheduler(2)->GetThreadList());
509 stop_threads(system.Scheduler(3)->GetThreadList());
504 510
505 // Kill the current thread 511 // Kill the current thread
506 GetCurrentThread()->Stop(); 512 GetCurrentThread()->Stop();
@@ -530,14 +536,9 @@ static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, V
530 536
531 switch (processor_id) { 537 switch (processor_id) {
532 case THREADPROCESSORID_0: 538 case THREADPROCESSORID_0:
533 break;
534 case THREADPROCESSORID_1: 539 case THREADPROCESSORID_1:
535 case THREADPROCESSORID_2: 540 case THREADPROCESSORID_2:
536 case THREADPROCESSORID_3: 541 case THREADPROCESSORID_3:
537 // TODO(bunnei): Implement support for other processor IDs
538 NGLOG_ERROR(Kernel_SVC,
539 "Newly created thread must run in another thread ({}), unimplemented.",
540 processor_id);
541 break; 542 break;
542 default: 543 default:
543 ASSERT_MSG(false, "Unsupported thread processor ID: {}", processor_id); 544 ASSERT_MSG(false, "Unsupported thread processor ID: {}", processor_id);
@@ -576,7 +577,7 @@ static ResultCode StartThread(Handle thread_handle) {
576 577
577/// Called when a thread exits 578/// Called when a thread exits
578static void ExitThread() { 579static void ExitThread() {
579 NGLOG_TRACE(Kernel_SVC, "called, pc=0x{:08X}", Core::CPU().GetPC()); 580 NGLOG_TRACE(Kernel_SVC, "called, pc=0x{:08X}", Core::CurrentArmInterface().GetPC());
580 581
581 ExitCurrentThread(); 582 ExitCurrentThread();
582 Core::System::GetInstance().PrepareReschedule(); 583 Core::System::GetInstance().PrepareReschedule();
@@ -588,7 +589,7 @@ static void SleepThread(s64 nanoseconds) {
588 589
589 // Don't attempt to yield execution if there are no available threads to run, 590 // Don't attempt to yield execution if there are no available threads to run,
590 // this way we avoid a useless reschedule to the idle thread. 591 // this way we avoid a useless reschedule to the idle thread.
591 if (nanoseconds == 0 && !Core::System::GetInstance().Scheduler().HaveReadyThreads()) 592 if (nanoseconds == 0 && !Core::System::GetInstance().CurrentScheduler().HaveReadyThreads())
592 return; 593 return;
593 594
594 // Sleep current thread and check for next thread to schedule 595 // Sleep current thread and check for next thread to schedule
@@ -634,7 +635,7 @@ static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target
634 condition_variable_addr, target); 635 condition_variable_addr, target);
635 636
636 u32 processed = 0; 637 u32 processed = 0;
637 auto& thread_list = Core::System::GetInstance().Scheduler().GetThreadList(); 638 auto& thread_list = Core::System::GetInstance().CurrentScheduler().GetThreadList();
638 639
639 for (auto& thread : thread_list) { 640 for (auto& thread : thread_list) {
640 if (thread->condvar_wait_address != condition_variable_addr) 641 if (thread->condvar_wait_address != condition_variable_addr)