summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2019-03-29 17:11:25 -0400
committerGravatar FernandoS272019-10-15 11:55:08 -0400
commit9031502974fa25c9c8521ad96ecc8126fcac51c6 (patch)
tree38c31670cd7c4445b158f76f524f2fa6d479f10d /src/core
parentRedesign CPU Cores to work with the new scheduler (diff)
downloadyuzu-9031502974fa25c9c8521ad96ecc8126fcac51c6.tar.gz
yuzu-9031502974fa25c9c8521ad96ecc8126fcac51c6.tar.xz
yuzu-9031502974fa25c9c8521ad96ecc8126fcac51c6.zip
Correct Supervisor Calls to work with the new scheduler,
Diffstat (limited to 'src/core')
-rw-r--r--src/core/hle/kernel/svc.cpp67
1 files changed, 41 insertions, 26 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 1fd1a732a..ee1e9f006 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -534,6 +534,8 @@ static ResultCode CancelSynchronization(Core::System& system, Handle thread_hand
534 } 534 }
535 535
536 thread->CancelWait(); 536 thread->CancelWait();
537 if (thread->GetProcessorID() >= 0)
538 Core::System::GetInstance().CpuCore(thread->GetProcessorID()).PrepareReschedule();
537 return RESULT_SUCCESS; 539 return RESULT_SUCCESS;
538} 540}
539 541
@@ -1066,6 +1068,9 @@ static ResultCode SetThreadActivity(Core::System& system, Handle handle, u32 act
1066 } 1068 }
1067 1069
1068 thread->SetActivity(static_cast<ThreadActivity>(activity)); 1070 thread->SetActivity(static_cast<ThreadActivity>(activity));
1071
1072 if (thread->GetProcessorID() >= 0)
1073 Core::System::GetInstance().CpuCore(thread->GetProcessorID()).PrepareReschedule();
1069 return RESULT_SUCCESS; 1074 return RESULT_SUCCESS;
1070} 1075}
1071 1076
@@ -1147,7 +1152,8 @@ static ResultCode SetThreadPriority(Core::System& system, Handle handle, u32 pri
1147 1152
1148 thread->SetPriority(priority); 1153 thread->SetPriority(priority);
1149 1154
1150 system.CpuCore(thread->GetProcessorID()).PrepareReschedule(); 1155 if (thread->GetProcessorID() >= 0)
1156 Core::System::GetInstance().CpuCore(thread->GetProcessorID()).PrepareReschedule();
1151 return RESULT_SUCCESS; 1157 return RESULT_SUCCESS;
1152} 1158}
1153 1159
@@ -1503,7 +1509,8 @@ static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr e
1503 thread->SetName( 1509 thread->SetName(
1504 fmt::format("thread[entry_point={:X}, handle={:X}]", entry_point, *new_thread_handle)); 1510 fmt::format("thread[entry_point={:X}, handle={:X}]", entry_point, *new_thread_handle));
1505 1511
1506 system.CpuCore(thread->GetProcessorID()).PrepareReschedule(); 1512 if (thread->GetProcessorID() >= 0)
1513 Core::System::GetInstance().CpuCore(thread->GetProcessorID()).PrepareReschedule();
1507 1514
1508 return RESULT_SUCCESS; 1515 return RESULT_SUCCESS;
1509} 1516}
@@ -1525,7 +1532,10 @@ static ResultCode StartThread(Core::System& system, Handle thread_handle) {
1525 thread->ResumeFromWait(); 1532 thread->ResumeFromWait();
1526 1533
1527 if (thread->GetStatus() == ThreadStatus::Ready) { 1534 if (thread->GetStatus() == ThreadStatus::Ready) {
1528 system.CpuCore(thread->GetProcessorID()).PrepareReschedule(); 1535 if (thread->GetProcessorID() >= 0)
1536 Core::System::GetInstance().CpuCore(thread->GetProcessorID()).PrepareReschedule();
1537 else
1538 Core::System::GetInstance().GlobalScheduler().SetReselectionPending();
1529 } 1539 }
1530 1540
1531 return RESULT_SUCCESS; 1541 return RESULT_SUCCESS;
@@ -1537,7 +1547,7 @@ static void ExitThread(Core::System& system) {
1537 1547
1538 auto* const current_thread = system.CurrentScheduler().GetCurrentThread(); 1548 auto* const current_thread = system.CurrentScheduler().GetCurrentThread();
1539 current_thread->Stop(); 1549 current_thread->Stop();
1540 system.CurrentScheduler().RemoveThread(current_thread); 1550 system.GlobalScheduler().RemoveThread(current_thread);
1541 system.PrepareReschedule(); 1551 system.PrepareReschedule();
1542} 1552}
1543 1553
@@ -1557,13 +1567,13 @@ static void SleepThread(Core::System& system, s64 nanoseconds) {
1557 if (nanoseconds <= 0) { 1567 if (nanoseconds <= 0) {
1558 switch (static_cast<SleepType>(nanoseconds)) { 1568 switch (static_cast<SleepType>(nanoseconds)) {
1559 case SleepType::YieldWithoutLoadBalancing: 1569 case SleepType::YieldWithoutLoadBalancing:
1560 scheduler.YieldWithoutLoadBalancing(current_thread); 1570 current_thread->YieldType0();
1561 break; 1571 break;
1562 case SleepType::YieldWithLoadBalancing: 1572 case SleepType::YieldWithLoadBalancing:
1563 scheduler.YieldWithLoadBalancing(current_thread); 1573 current_thread->YieldType1();
1564 break; 1574 break;
1565 case SleepType::YieldAndWaitForLoadBalancing: 1575 case SleepType::YieldAndWaitForLoadBalancing:
1566 scheduler.YieldAndWaitForLoadBalancing(current_thread); 1576 current_thread->YieldType2();
1567 break; 1577 break;
1568 default: 1578 default:
1569 UNREACHABLE_MSG("Unimplemented sleep yield type '{:016X}'!", nanoseconds); 1579 UNREACHABLE_MSG("Unimplemented sleep yield type '{:016X}'!", nanoseconds);
@@ -1632,24 +1642,16 @@ static ResultCode SignalProcessWideKey(Core::System& system, VAddr condition_var
1632 LOG_TRACE(Kernel_SVC, "called, condition_variable_addr=0x{:X}, target=0x{:08X}", 1642 LOG_TRACE(Kernel_SVC, "called, condition_variable_addr=0x{:X}, target=0x{:08X}",
1633 condition_variable_addr, target); 1643 condition_variable_addr, target);
1634 1644
1635 const auto RetrieveWaitingThreads = [&system](std::size_t core_index,
1636 std::vector<SharedPtr<Thread>>& waiting_threads,
1637 VAddr condvar_addr) {
1638 const auto& scheduler = system.Scheduler(core_index);
1639 const auto& thread_list = scheduler.GetThreadList();
1640
1641 for (const auto& thread : thread_list) {
1642 if (thread->GetCondVarWaitAddress() == condvar_addr)
1643 waiting_threads.push_back(thread);
1644 }
1645 };
1646
1647 // Retrieve a list of all threads that are waiting for this condition variable. 1645 // Retrieve a list of all threads that are waiting for this condition variable.
1648 std::vector<SharedPtr<Thread>> waiting_threads; 1646 std::vector<SharedPtr<Thread>> waiting_threads;
1649 RetrieveWaitingThreads(0, waiting_threads, condition_variable_addr); 1647 const auto& scheduler = Core::System::GetInstance().GlobalScheduler();
1650 RetrieveWaitingThreads(1, waiting_threads, condition_variable_addr); 1648 const auto& thread_list = scheduler.GetThreadList();
1651 RetrieveWaitingThreads(2, waiting_threads, condition_variable_addr); 1649
1652 RetrieveWaitingThreads(3, waiting_threads, condition_variable_addr); 1650 for (const auto& thread : thread_list) {
1651 if (thread->GetCondVarWaitAddress() == condition_variable_addr)
1652 waiting_threads.push_back(thread);
1653 }
1654
1653 // Sort them by priority, such that the highest priority ones come first. 1655 // Sort them by priority, such that the highest priority ones come first.
1654 std::sort(waiting_threads.begin(), waiting_threads.end(), 1656 std::sort(waiting_threads.begin(), waiting_threads.end(),
1655 [](const SharedPtr<Thread>& lhs, const SharedPtr<Thread>& rhs) { 1657 [](const SharedPtr<Thread>& lhs, const SharedPtr<Thread>& rhs) {
@@ -1704,7 +1706,8 @@ static ResultCode SignalProcessWideKey(Core::System& system, VAddr condition_var
1704 thread->SetLockOwner(nullptr); 1706 thread->SetLockOwner(nullptr);
1705 thread->SetMutexWaitAddress(0); 1707 thread->SetMutexWaitAddress(0);
1706 thread->SetWaitHandle(0); 1708 thread->SetWaitHandle(0);
1707 system.CpuCore(thread->GetProcessorID()).PrepareReschedule(); 1709 if (thread->GetProcessorID() >= 0)
1710 Core::System::GetInstance().CpuCore(thread->GetProcessorID()).PrepareReschedule();
1708 } else { 1711 } else {
1709 // Atomically signal that the mutex now has a waiting thread. 1712 // Atomically signal that the mutex now has a waiting thread.
1710 do { 1713 do {
@@ -1728,6 +1731,8 @@ static ResultCode SignalProcessWideKey(Core::System& system, VAddr condition_var
1728 thread->SetStatus(ThreadStatus::WaitMutex); 1731 thread->SetStatus(ThreadStatus::WaitMutex);
1729 1732
1730 owner->AddMutexWaiter(thread); 1733 owner->AddMutexWaiter(thread);
1734 if (thread->GetProcessorID() >= 0)
1735 Core::System::GetInstance().CpuCore(thread->GetProcessorID()).PrepareReschedule();
1731 } 1736 }
1732 } 1737 }
1733 1738
@@ -1753,8 +1758,14 @@ static ResultCode WaitForAddress(Core::System& system, VAddr address, u32 type,
1753 } 1758 }
1754 1759
1755 const auto arbitration_type = static_cast<AddressArbiter::ArbitrationType>(type); 1760 const auto arbitration_type = static_cast<AddressArbiter::ArbitrationType>(type);
1756 auto& address_arbiter = system.Kernel().CurrentProcess()->GetAddressArbiter(); 1761 auto& address_arbiter =
1757 return address_arbiter.WaitForAddress(address, arbitration_type, value, timeout); 1762 system.Kernel().CurrentProcess()->GetAddressArbiter();
1763 ResultCode result = address_arbiter.WaitForAddress(address, arbitration_type, value, timeout);
1764 if (result == RESULT_SUCCESS)
1765 Core::System::GetInstance()
1766 .CpuCore(GetCurrentThread()->GetProcessorID())
1767 .PrepareReschedule();
1768 return result;
1758} 1769}
1759 1770
1760// Signals to an address (via Address Arbiter) 1771// Signals to an address (via Address Arbiter)
@@ -2040,7 +2051,10 @@ static ResultCode SetThreadCoreMask(Core::System& system, Handle thread_handle,
2040 return ERR_INVALID_HANDLE; 2051 return ERR_INVALID_HANDLE;
2041 } 2052 }
2042 2053
2054 Core::System::GetInstance().CpuCore(thread->GetProcessorID()).PrepareReschedule();
2043 thread->ChangeCore(core, affinity_mask); 2055 thread->ChangeCore(core, affinity_mask);
2056 if (thread->GetProcessorID() >= 0)
2057 Core::System::GetInstance().CpuCore(thread->GetProcessorID()).PrepareReschedule();
2044 return RESULT_SUCCESS; 2058 return RESULT_SUCCESS;
2045} 2059}
2046 2060
@@ -2151,6 +2165,7 @@ static ResultCode SignalEvent(Core::System& system, Handle handle) {
2151 } 2165 }
2152 2166
2153 writable_event->Signal(); 2167 writable_event->Signal();
2168 Core::System::GetInstance().PrepareReschedule();
2154 return RESULT_SUCCESS; 2169 return RESULT_SUCCESS;
2155} 2170}
2156 2171