diff options
| author | 2020-12-02 18:08:35 -0800 | |
|---|---|---|
| committer | 2020-12-06 00:03:24 -0800 | |
| commit | 9e29e36a784496f7290c03b6a42e400a164a5b1e (patch) | |
| tree | d33cc91b4651b374e0c244be7b7e3b47ef7680fd /src/core/hle/kernel/svc.cpp | |
| parent | hle: kernel: physical_core: Clear exclusive state after each run. (diff) | |
| download | yuzu-9e29e36a784496f7290c03b6a42e400a164a5b1e.tar.gz yuzu-9e29e36a784496f7290c03b6a42e400a164a5b1e.tar.xz yuzu-9e29e36a784496f7290c03b6a42e400a164a5b1e.zip | |
hle: kernel: Rewrite scheduler implementation based on Mesopshere.
Diffstat (limited to 'src/core/hle/kernel/svc.cpp')
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 57 |
1 files changed, 26 insertions, 31 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 9742aaf4c..2612a6b0d 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | #include "core/hle/kernel/client_session.h" | 24 | #include "core/hle/kernel/client_session.h" |
| 25 | #include "core/hle/kernel/errors.h" | 25 | #include "core/hle/kernel/errors.h" |
| 26 | #include "core/hle/kernel/handle_table.h" | 26 | #include "core/hle/kernel/handle_table.h" |
| 27 | #include "core/hle/kernel/k_scheduler.h" | ||
| 27 | #include "core/hle/kernel/kernel.h" | 28 | #include "core/hle/kernel/kernel.h" |
| 28 | #include "core/hle/kernel/memory/memory_block.h" | 29 | #include "core/hle/kernel/memory/memory_block.h" |
| 29 | #include "core/hle/kernel/memory/page_table.h" | 30 | #include "core/hle/kernel/memory/page_table.h" |
| @@ -32,7 +33,6 @@ | |||
| 32 | #include "core/hle/kernel/process.h" | 33 | #include "core/hle/kernel/process.h" |
| 33 | #include "core/hle/kernel/readable_event.h" | 34 | #include "core/hle/kernel/readable_event.h" |
| 34 | #include "core/hle/kernel/resource_limit.h" | 35 | #include "core/hle/kernel/resource_limit.h" |
| 35 | #include "core/hle/kernel/scheduler.h" | ||
| 36 | #include "core/hle/kernel/shared_memory.h" | 36 | #include "core/hle/kernel/shared_memory.h" |
| 37 | #include "core/hle/kernel/svc.h" | 37 | #include "core/hle/kernel/svc.h" |
| 38 | #include "core/hle/kernel/svc_types.h" | 38 | #include "core/hle/kernel/svc_types.h" |
| @@ -332,7 +332,8 @@ static ResultCode ConnectToNamedPort32(Core::System& system, Handle* out_handle, | |||
| 332 | 332 | ||
| 333 | /// Makes a blocking IPC call to an OS service. | 333 | /// Makes a blocking IPC call to an OS service. |
| 334 | static ResultCode SendSyncRequest(Core::System& system, Handle handle) { | 334 | static ResultCode SendSyncRequest(Core::System& system, Handle handle) { |
| 335 | const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); | 335 | auto& kernel = system.Kernel(); |
| 336 | const auto& handle_table = kernel.CurrentProcess()->GetHandleTable(); | ||
| 336 | std::shared_ptr<ClientSession> session = handle_table.Get<ClientSession>(handle); | 337 | std::shared_ptr<ClientSession> session = handle_table.Get<ClientSession>(handle); |
| 337 | if (!session) { | 338 | if (!session) { |
| 338 | LOG_ERROR(Kernel_SVC, "called with invalid handle=0x{:08X}", handle); | 339 | LOG_ERROR(Kernel_SVC, "called with invalid handle=0x{:08X}", handle); |
| @@ -341,9 +342,9 @@ static ResultCode SendSyncRequest(Core::System& system, Handle handle) { | |||
| 341 | 342 | ||
| 342 | LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}({})", handle, session->GetName()); | 343 | LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}({})", handle, session->GetName()); |
| 343 | 344 | ||
| 344 | auto thread = system.CurrentScheduler().GetCurrentThread(); | 345 | auto thread = kernel.CurrentScheduler()->GetCurrentThread(); |
| 345 | { | 346 | { |
| 346 | SchedulerLock lock(system.Kernel()); | 347 | SchedulerLock lock(kernel); |
| 347 | thread->InvalidateHLECallback(); | 348 | thread->InvalidateHLECallback(); |
| 348 | thread->SetStatus(ThreadStatus::WaitIPC); | 349 | thread->SetStatus(ThreadStatus::WaitIPC); |
| 349 | session->SendSyncRequest(SharedFrom(thread), system.Memory(), system.CoreTiming()); | 350 | session->SendSyncRequest(SharedFrom(thread), system.Memory(), system.CoreTiming()); |
| @@ -352,12 +353,12 @@ static ResultCode SendSyncRequest(Core::System& system, Handle handle) { | |||
| 352 | if (thread->HasHLECallback()) { | 353 | if (thread->HasHLECallback()) { |
| 353 | Handle event_handle = thread->GetHLETimeEvent(); | 354 | Handle event_handle = thread->GetHLETimeEvent(); |
| 354 | if (event_handle != InvalidHandle) { | 355 | if (event_handle != InvalidHandle) { |
| 355 | auto& time_manager = system.Kernel().TimeManager(); | 356 | auto& time_manager = kernel.TimeManager(); |
| 356 | time_manager.UnscheduleTimeEvent(event_handle); | 357 | time_manager.UnscheduleTimeEvent(event_handle); |
| 357 | } | 358 | } |
| 358 | 359 | ||
| 359 | { | 360 | { |
| 360 | SchedulerLock lock(system.Kernel()); | 361 | SchedulerLock lock(kernel); |
| 361 | auto* sync_object = thread->GetHLESyncObject(); | 362 | auto* sync_object = thread->GetHLESyncObject(); |
| 362 | sync_object->RemoveWaitingThread(SharedFrom(thread)); | 363 | sync_object->RemoveWaitingThread(SharedFrom(thread)); |
| 363 | } | 364 | } |
| @@ -665,7 +666,7 @@ static void Break(Core::System& system, u32 reason, u64 info1, u64 info2) { | |||
| 665 | 666 | ||
| 666 | handle_debug_buffer(info1, info2); | 667 | handle_debug_buffer(info1, info2); |
| 667 | 668 | ||
| 668 | auto* const current_thread = system.CurrentScheduler().GetCurrentThread(); | 669 | auto* const current_thread = system.Kernel().CurrentScheduler()->GetCurrentThread(); |
| 669 | const auto thread_processor_id = current_thread->GetProcessorID(); | 670 | const auto thread_processor_id = current_thread->GetProcessorID(); |
| 670 | system.ArmInterface(static_cast<std::size_t>(thread_processor_id)).LogBacktrace(); | 671 | system.ArmInterface(static_cast<std::size_t>(thread_processor_id)).LogBacktrace(); |
| 671 | } | 672 | } |
| @@ -917,7 +918,7 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, u64 ha | |||
| 917 | } | 918 | } |
| 918 | 919 | ||
| 919 | const auto& core_timing = system.CoreTiming(); | 920 | const auto& core_timing = system.CoreTiming(); |
| 920 | const auto& scheduler = system.CurrentScheduler(); | 921 | const auto& scheduler = *system.Kernel().CurrentScheduler(); |
| 921 | const auto* const current_thread = scheduler.GetCurrentThread(); | 922 | const auto* const current_thread = scheduler.GetCurrentThread(); |
| 922 | const bool same_thread = current_thread == thread.get(); | 923 | const bool same_thread = current_thread == thread.get(); |
| 923 | 924 | ||
| @@ -1085,7 +1086,7 @@ static ResultCode SetThreadActivity(Core::System& system, Handle handle, u32 act | |||
| 1085 | return ERR_INVALID_HANDLE; | 1086 | return ERR_INVALID_HANDLE; |
| 1086 | } | 1087 | } |
| 1087 | 1088 | ||
| 1088 | if (thread.get() == system.CurrentScheduler().GetCurrentThread()) { | 1089 | if (thread.get() == system.Kernel().CurrentScheduler()->GetCurrentThread()) { |
| 1089 | LOG_ERROR(Kernel_SVC, "The thread handle specified is the current running thread"); | 1090 | LOG_ERROR(Kernel_SVC, "The thread handle specified is the current running thread"); |
| 1090 | return ERR_BUSY; | 1091 | return ERR_BUSY; |
| 1091 | } | 1092 | } |
| @@ -1118,7 +1119,7 @@ static ResultCode GetThreadContext(Core::System& system, VAddr thread_context, H | |||
| 1118 | return ERR_INVALID_HANDLE; | 1119 | return ERR_INVALID_HANDLE; |
| 1119 | } | 1120 | } |
| 1120 | 1121 | ||
| 1121 | if (thread.get() == system.CurrentScheduler().GetCurrentThread()) { | 1122 | if (thread.get() == system.Kernel().CurrentScheduler()->GetCurrentThread()) { |
| 1122 | LOG_ERROR(Kernel_SVC, "The thread handle specified is the current running thread"); | 1123 | LOG_ERROR(Kernel_SVC, "The thread handle specified is the current running thread"); |
| 1123 | return ERR_BUSY; | 1124 | return ERR_BUSY; |
| 1124 | } | 1125 | } |
| @@ -1475,7 +1476,7 @@ static void ExitProcess(Core::System& system) { | |||
| 1475 | current_process->PrepareForTermination(); | 1476 | current_process->PrepareForTermination(); |
| 1476 | 1477 | ||
| 1477 | // Kill the current thread | 1478 | // Kill the current thread |
| 1478 | system.CurrentScheduler().GetCurrentThread()->Stop(); | 1479 | system.Kernel().CurrentScheduler()->GetCurrentThread()->Stop(); |
| 1479 | } | 1480 | } |
| 1480 | 1481 | ||
| 1481 | static void ExitProcess32(Core::System& system) { | 1482 | static void ExitProcess32(Core::System& system) { |
| @@ -1576,8 +1577,8 @@ static ResultCode StartThread32(Core::System& system, Handle thread_handle) { | |||
| 1576 | static void ExitThread(Core::System& system) { | 1577 | static void ExitThread(Core::System& system) { |
| 1577 | LOG_DEBUG(Kernel_SVC, "called, pc=0x{:08X}", system.CurrentArmInterface().GetPC()); | 1578 | LOG_DEBUG(Kernel_SVC, "called, pc=0x{:08X}", system.CurrentArmInterface().GetPC()); |
| 1578 | 1579 | ||
| 1579 | auto* const current_thread = system.CurrentScheduler().GetCurrentThread(); | 1580 | auto* const current_thread = system.Kernel().CurrentScheduler()->GetCurrentThread(); |
| 1580 | system.GlobalScheduler().RemoveThread(SharedFrom(current_thread)); | 1581 | system.GlobalSchedulerContext().RemoveThread(SharedFrom(current_thread)); |
| 1581 | current_thread->Stop(); | 1582 | current_thread->Stop(); |
| 1582 | } | 1583 | } |
| 1583 | 1584 | ||
| @@ -1590,37 +1591,31 @@ static void SleepThread(Core::System& system, s64 nanoseconds) { | |||
| 1590 | LOG_DEBUG(Kernel_SVC, "called nanoseconds={}", nanoseconds); | 1591 | LOG_DEBUG(Kernel_SVC, "called nanoseconds={}", nanoseconds); |
| 1591 | 1592 | ||
| 1592 | enum class SleepType : s64 { | 1593 | enum class SleepType : s64 { |
| 1593 | YieldWithoutLoadBalancing = 0, | 1594 | YieldWithoutCoreMigration = 0, |
| 1594 | YieldWithLoadBalancing = -1, | 1595 | YieldWithCoreMigration = -1, |
| 1595 | YieldAndWaitForLoadBalancing = -2, | 1596 | YieldAndWaitForLoadBalancing = -2, |
| 1596 | }; | 1597 | }; |
| 1597 | 1598 | ||
| 1598 | auto& scheduler = system.CurrentScheduler(); | 1599 | auto& scheduler = *system.Kernel().CurrentScheduler(); |
| 1599 | auto* const current_thread = scheduler.GetCurrentThread(); | ||
| 1600 | bool is_redundant = false; | ||
| 1601 | |||
| 1602 | if (nanoseconds <= 0) { | 1600 | if (nanoseconds <= 0) { |
| 1603 | switch (static_cast<SleepType>(nanoseconds)) { | 1601 | switch (static_cast<SleepType>(nanoseconds)) { |
| 1604 | case SleepType::YieldWithoutLoadBalancing: { | 1602 | case SleepType::YieldWithoutCoreMigration: { |
| 1605 | auto pair = current_thread->YieldSimple(); | 1603 | scheduler.YieldWithoutCoreMigration(); |
| 1606 | is_redundant = pair.second; | ||
| 1607 | break; | 1604 | break; |
| 1608 | } | 1605 | } |
| 1609 | case SleepType::YieldWithLoadBalancing: { | 1606 | case SleepType::YieldWithCoreMigration: { |
| 1610 | auto pair = current_thread->YieldAndBalanceLoad(); | 1607 | scheduler.YieldWithCoreMigration(); |
| 1611 | is_redundant = pair.second; | ||
| 1612 | break; | 1608 | break; |
| 1613 | } | 1609 | } |
| 1614 | case SleepType::YieldAndWaitForLoadBalancing: { | 1610 | case SleepType::YieldAndWaitForLoadBalancing: { |
| 1615 | auto pair = current_thread->YieldAndWaitForLoadBalancing(); | 1611 | scheduler.YieldToAnyThread(); |
| 1616 | is_redundant = pair.second; | ||
| 1617 | break; | 1612 | break; |
| 1618 | } | 1613 | } |
| 1619 | default: | 1614 | default: |
| 1620 | UNREACHABLE_MSG("Unimplemented sleep yield type '{:016X}'!", nanoseconds); | 1615 | UNREACHABLE_MSG("Unimplemented sleep yield type '{:016X}'!", nanoseconds); |
| 1621 | } | 1616 | } |
| 1622 | } else { | 1617 | } else { |
| 1623 | current_thread->Sleep(nanoseconds); | 1618 | scheduler.GetCurrentThread()->Sleep(nanoseconds); |
| 1624 | } | 1619 | } |
| 1625 | } | 1620 | } |
| 1626 | 1621 | ||
| @@ -1656,8 +1651,8 @@ static ResultCode WaitProcessWideKeyAtomic(Core::System& system, VAddr mutex_add | |||
| 1656 | ASSERT(condition_variable_addr == Common::AlignDown(condition_variable_addr, 4)); | 1651 | ASSERT(condition_variable_addr == Common::AlignDown(condition_variable_addr, 4)); |
| 1657 | auto& kernel = system.Kernel(); | 1652 | auto& kernel = system.Kernel(); |
| 1658 | Handle event_handle; | 1653 | Handle event_handle; |
| 1659 | Thread* current_thread = system.CurrentScheduler().GetCurrentThread(); | 1654 | Thread* current_thread = kernel.CurrentScheduler()->GetCurrentThread(); |
| 1660 | auto* const current_process = system.Kernel().CurrentProcess(); | 1655 | auto* const current_process = kernel.CurrentProcess(); |
| 1661 | { | 1656 | { |
| 1662 | SchedulerLockAndSleep lock(kernel, event_handle, current_thread, nano_seconds); | 1657 | SchedulerLockAndSleep lock(kernel, event_handle, current_thread, nano_seconds); |
| 1663 | const auto& handle_table = current_process->GetHandleTable(); | 1658 | const auto& handle_table = current_process->GetHandleTable(); |
| @@ -2627,7 +2622,7 @@ void Call(Core::System& system, u32 immediate) { | |||
| 2627 | auto& kernel = system.Kernel(); | 2622 | auto& kernel = system.Kernel(); |
| 2628 | kernel.EnterSVCProfile(); | 2623 | kernel.EnterSVCProfile(); |
| 2629 | 2624 | ||
| 2630 | auto* thread = system.CurrentScheduler().GetCurrentThread(); | 2625 | auto* thread = kernel.CurrentScheduler()->GetCurrentThread(); |
| 2631 | thread->SetContinuousOnSVC(true); | 2626 | thread->SetContinuousOnSVC(true); |
| 2632 | 2627 | ||
| 2633 | const FunctionDef* info = system.CurrentProcess()->Is64BitProcess() ? GetSVCInfo64(immediate) | 2628 | const FunctionDef* info = system.CurrentProcess()->Is64BitProcess() ? GetSVCInfo64(immediate) |