diff options
| author | 2019-03-29 17:11:25 -0400 | |
|---|---|---|
| committer | 2019-10-15 11:55:08 -0400 | |
| commit | 9031502974fa25c9c8521ad96ecc8126fcac51c6 (patch) | |
| tree | 38c31670cd7c4445b158f76f524f2fa6d479f10d /src/core | |
| parent | Redesign CPU Cores to work with the new scheduler (diff) | |
| download | yuzu-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.cpp | 67 |
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 | ||