summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/svc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/kernel/svc.cpp')
-rw-r--r--src/core/hle/kernel/svc.cpp78
1 files changed, 31 insertions, 47 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index c8060f179..2d225392f 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -24,6 +24,8 @@
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"
28#include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h"
27#include "core/hle/kernel/kernel.h" 29#include "core/hle/kernel/kernel.h"
28#include "core/hle/kernel/memory/memory_block.h" 30#include "core/hle/kernel/memory/memory_block.h"
29#include "core/hle/kernel/memory/page_table.h" 31#include "core/hle/kernel/memory/page_table.h"
@@ -32,7 +34,6 @@
32#include "core/hle/kernel/process.h" 34#include "core/hle/kernel/process.h"
33#include "core/hle/kernel/readable_event.h" 35#include "core/hle/kernel/readable_event.h"
34#include "core/hle/kernel/resource_limit.h" 36#include "core/hle/kernel/resource_limit.h"
35#include "core/hle/kernel/scheduler.h"
36#include "core/hle/kernel/shared_memory.h" 37#include "core/hle/kernel/shared_memory.h"
37#include "core/hle/kernel/svc.h" 38#include "core/hle/kernel/svc.h"
38#include "core/hle/kernel/svc_types.h" 39#include "core/hle/kernel/svc_types.h"
@@ -329,7 +330,8 @@ static ResultCode ConnectToNamedPort32(Core::System& system, Handle* out_handle,
329 330
330/// Makes a blocking IPC call to an OS service. 331/// Makes a blocking IPC call to an OS service.
331static ResultCode SendSyncRequest(Core::System& system, Handle handle) { 332static ResultCode SendSyncRequest(Core::System& system, Handle handle) {
332 const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); 333 auto& kernel = system.Kernel();
334 const auto& handle_table = kernel.CurrentProcess()->GetHandleTable();
333 std::shared_ptr<ClientSession> session = handle_table.Get<ClientSession>(handle); 335 std::shared_ptr<ClientSession> session = handle_table.Get<ClientSession>(handle);
334 if (!session) { 336 if (!session) {
335 LOG_ERROR(Kernel_SVC, "called with invalid handle=0x{:08X}", handle); 337 LOG_ERROR(Kernel_SVC, "called with invalid handle=0x{:08X}", handle);
@@ -338,9 +340,9 @@ static ResultCode SendSyncRequest(Core::System& system, Handle handle) {
338 340
339 LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}({})", handle, session->GetName()); 341 LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}({})", handle, session->GetName());
340 342
341 auto thread = system.CurrentScheduler().GetCurrentThread(); 343 auto thread = kernel.CurrentScheduler()->GetCurrentThread();
342 { 344 {
343 SchedulerLock lock(system.Kernel()); 345 KScopedSchedulerLock lock(kernel);
344 thread->InvalidateHLECallback(); 346 thread->InvalidateHLECallback();
345 thread->SetStatus(ThreadStatus::WaitIPC); 347 thread->SetStatus(ThreadStatus::WaitIPC);
346 session->SendSyncRequest(SharedFrom(thread), system.Memory(), system.CoreTiming()); 348 session->SendSyncRequest(SharedFrom(thread), system.Memory(), system.CoreTiming());
@@ -349,12 +351,12 @@ static ResultCode SendSyncRequest(Core::System& system, Handle handle) {
349 if (thread->HasHLECallback()) { 351 if (thread->HasHLECallback()) {
350 Handle event_handle = thread->GetHLETimeEvent(); 352 Handle event_handle = thread->GetHLETimeEvent();
351 if (event_handle != InvalidHandle) { 353 if (event_handle != InvalidHandle) {
352 auto& time_manager = system.Kernel().TimeManager(); 354 auto& time_manager = kernel.TimeManager();
353 time_manager.UnscheduleTimeEvent(event_handle); 355 time_manager.UnscheduleTimeEvent(event_handle);
354 } 356 }
355 357
356 { 358 {
357 SchedulerLock lock(system.Kernel()); 359 KScopedSchedulerLock lock(kernel);
358 auto* sync_object = thread->GetHLESyncObject(); 360 auto* sync_object = thread->GetHLESyncObject();
359 sync_object->RemoveWaitingThread(SharedFrom(thread)); 361 sync_object->RemoveWaitingThread(SharedFrom(thread));
360 } 362 }
@@ -654,7 +656,6 @@ static void Break(Core::System& system, u32 reason, u64 info1, u64 info2) {
654 info2, has_dumped_buffer ? std::make_optional(debug_buffer) : std::nullopt); 656 info2, has_dumped_buffer ? std::make_optional(debug_buffer) : std::nullopt);
655 657
656 if (!break_reason.signal_debugger) { 658 if (!break_reason.signal_debugger) {
657 SchedulerLock lock(system.Kernel());
658 LOG_CRITICAL( 659 LOG_CRITICAL(
659 Debug_Emulated, 660 Debug_Emulated,
660 "Emulated program broke execution! reason=0x{:016X}, info1=0x{:016X}, info2=0x{:016X}", 661 "Emulated program broke execution! reason=0x{:016X}, info1=0x{:016X}, info2=0x{:016X}",
@@ -662,13 +663,9 @@ static void Break(Core::System& system, u32 reason, u64 info1, u64 info2) {
662 663
663 handle_debug_buffer(info1, info2); 664 handle_debug_buffer(info1, info2);
664 665
665 auto* const current_thread = system.CurrentScheduler().GetCurrentThread(); 666 auto* const current_thread = system.Kernel().CurrentScheduler()->GetCurrentThread();
666 const auto thread_processor_id = current_thread->GetProcessorID(); 667 const auto thread_processor_id = current_thread->GetProcessorID();
667 system.ArmInterface(static_cast<std::size_t>(thread_processor_id)).LogBacktrace(); 668 system.ArmInterface(static_cast<std::size_t>(thread_processor_id)).LogBacktrace();
668
669 // Kill the current thread
670 system.Kernel().ExceptionalExit();
671 current_thread->Stop();
672 } 669 }
673} 670}
674 671
@@ -918,7 +915,7 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, u64 ha
918 } 915 }
919 916
920 const auto& core_timing = system.CoreTiming(); 917 const auto& core_timing = system.CoreTiming();
921 const auto& scheduler = system.CurrentScheduler(); 918 const auto& scheduler = *system.Kernel().CurrentScheduler();
922 const auto* const current_thread = scheduler.GetCurrentThread(); 919 const auto* const current_thread = scheduler.GetCurrentThread();
923 const bool same_thread = current_thread == thread.get(); 920 const bool same_thread = current_thread == thread.get();
924 921
@@ -1086,7 +1083,7 @@ static ResultCode SetThreadActivity(Core::System& system, Handle handle, u32 act
1086 return ERR_INVALID_HANDLE; 1083 return ERR_INVALID_HANDLE;
1087 } 1084 }
1088 1085
1089 if (thread.get() == system.CurrentScheduler().GetCurrentThread()) { 1086 if (thread.get() == system.Kernel().CurrentScheduler()->GetCurrentThread()) {
1090 LOG_ERROR(Kernel_SVC, "The thread handle specified is the current running thread"); 1087 LOG_ERROR(Kernel_SVC, "The thread handle specified is the current running thread");
1091 return ERR_BUSY; 1088 return ERR_BUSY;
1092 } 1089 }
@@ -1119,7 +1116,7 @@ static ResultCode GetThreadContext(Core::System& system, VAddr thread_context, H
1119 return ERR_INVALID_HANDLE; 1116 return ERR_INVALID_HANDLE;
1120 } 1117 }
1121 1118
1122 if (thread.get() == system.CurrentScheduler().GetCurrentThread()) { 1119 if (thread.get() == system.Kernel().CurrentScheduler()->GetCurrentThread()) {
1123 LOG_ERROR(Kernel_SVC, "The thread handle specified is the current running thread"); 1120 LOG_ERROR(Kernel_SVC, "The thread handle specified is the current running thread");
1124 return ERR_BUSY; 1121 return ERR_BUSY;
1125 } 1122 }
@@ -1475,7 +1472,7 @@ static void ExitProcess(Core::System& system) {
1475 current_process->PrepareForTermination(); 1472 current_process->PrepareForTermination();
1476 1473
1477 // Kill the current thread 1474 // Kill the current thread
1478 system.CurrentScheduler().GetCurrentThread()->Stop(); 1475 system.Kernel().CurrentScheduler()->GetCurrentThread()->Stop();
1479} 1476}
1480 1477
1481static void ExitProcess32(Core::System& system) { 1478static void ExitProcess32(Core::System& system) {
@@ -1575,8 +1572,8 @@ static ResultCode StartThread32(Core::System& system, Handle thread_handle) {
1575static void ExitThread(Core::System& system) { 1572static void ExitThread(Core::System& system) {
1576 LOG_DEBUG(Kernel_SVC, "called, pc=0x{:08X}", system.CurrentArmInterface().GetPC()); 1573 LOG_DEBUG(Kernel_SVC, "called, pc=0x{:08X}", system.CurrentArmInterface().GetPC());
1577 1574
1578 auto* const current_thread = system.CurrentScheduler().GetCurrentThread(); 1575 auto* const current_thread = system.Kernel().CurrentScheduler()->GetCurrentThread();
1579 system.GlobalScheduler().RemoveThread(SharedFrom(current_thread)); 1576 system.GlobalSchedulerContext().RemoveThread(SharedFrom(current_thread));
1580 current_thread->Stop(); 1577 current_thread->Stop();
1581} 1578}
1582 1579
@@ -1589,44 +1586,31 @@ static void SleepThread(Core::System& system, s64 nanoseconds) {
1589 LOG_DEBUG(Kernel_SVC, "called nanoseconds={}", nanoseconds); 1586 LOG_DEBUG(Kernel_SVC, "called nanoseconds={}", nanoseconds);
1590 1587
1591 enum class SleepType : s64 { 1588 enum class SleepType : s64 {
1592 YieldWithoutLoadBalancing = 0, 1589 YieldWithoutCoreMigration = 0,
1593 YieldWithLoadBalancing = -1, 1590 YieldWithCoreMigration = -1,
1594 YieldAndWaitForLoadBalancing = -2, 1591 YieldAndWaitForLoadBalancing = -2,
1595 }; 1592 };
1596 1593
1597 auto& scheduler = system.CurrentScheduler(); 1594 auto& scheduler = *system.Kernel().CurrentScheduler();
1598 auto* const current_thread = scheduler.GetCurrentThread();
1599 bool is_redundant = false;
1600
1601 if (nanoseconds <= 0) { 1595 if (nanoseconds <= 0) {
1602 switch (static_cast<SleepType>(nanoseconds)) { 1596 switch (static_cast<SleepType>(nanoseconds)) {
1603 case SleepType::YieldWithoutLoadBalancing: { 1597 case SleepType::YieldWithoutCoreMigration: {
1604 auto pair = current_thread->YieldSimple(); 1598 scheduler.YieldWithoutCoreMigration();
1605 is_redundant = pair.second;
1606 break; 1599 break;
1607 } 1600 }
1608 case SleepType::YieldWithLoadBalancing: { 1601 case SleepType::YieldWithCoreMigration: {
1609 auto pair = current_thread->YieldAndBalanceLoad(); 1602 scheduler.YieldWithCoreMigration();
1610 is_redundant = pair.second;
1611 break; 1603 break;
1612 } 1604 }
1613 case SleepType::YieldAndWaitForLoadBalancing: { 1605 case SleepType::YieldAndWaitForLoadBalancing: {
1614 auto pair = current_thread->YieldAndWaitForLoadBalancing(); 1606 scheduler.YieldToAnyThread();
1615 is_redundant = pair.second;
1616 break; 1607 break;
1617 } 1608 }
1618 default: 1609 default:
1619 UNREACHABLE_MSG("Unimplemented sleep yield type '{:016X}'!", nanoseconds); 1610 UNREACHABLE_MSG("Unimplemented sleep yield type '{:016X}'!", nanoseconds);
1620 } 1611 }
1621 } else { 1612 } else {
1622 current_thread->Sleep(nanoseconds); 1613 scheduler.GetCurrentThread()->Sleep(nanoseconds);
1623 }
1624
1625 if (is_redundant && !system.Kernel().IsMulticore()) {
1626 system.Kernel().ExitSVCProfile();
1627 system.CoreTiming().AddTicks(1000U);
1628 system.GetCpuManager().PreemptSingleCore();
1629 system.Kernel().EnterSVCProfile();
1630 } 1614 }
1631} 1615}
1632 1616
@@ -1661,10 +1645,10 @@ static ResultCode WaitProcessWideKeyAtomic(Core::System& system, VAddr mutex_add
1661 ASSERT(condition_variable_addr == Common::AlignDown(condition_variable_addr, 4)); 1645 ASSERT(condition_variable_addr == Common::AlignDown(condition_variable_addr, 4));
1662 auto& kernel = system.Kernel(); 1646 auto& kernel = system.Kernel();
1663 Handle event_handle; 1647 Handle event_handle;
1664 Thread* current_thread = system.CurrentScheduler().GetCurrentThread(); 1648 Thread* current_thread = kernel.CurrentScheduler()->GetCurrentThread();
1665 auto* const current_process = system.Kernel().CurrentProcess(); 1649 auto* const current_process = kernel.CurrentProcess();
1666 { 1650 {
1667 SchedulerLockAndSleep lock(kernel, event_handle, current_thread, nano_seconds); 1651 KScopedSchedulerLockAndSleep lock(kernel, event_handle, current_thread, nano_seconds);
1668 const auto& handle_table = current_process->GetHandleTable(); 1652 const auto& handle_table = current_process->GetHandleTable();
1669 std::shared_ptr<Thread> thread = handle_table.Get<Thread>(thread_handle); 1653 std::shared_ptr<Thread> thread = handle_table.Get<Thread>(thread_handle);
1670 ASSERT(thread); 1654 ASSERT(thread);
@@ -1700,7 +1684,7 @@ static ResultCode WaitProcessWideKeyAtomic(Core::System& system, VAddr mutex_add
1700 } 1684 }
1701 1685
1702 { 1686 {
1703 SchedulerLock lock(kernel); 1687 KScopedSchedulerLock lock(kernel);
1704 1688
1705 auto* owner = current_thread->GetLockOwner(); 1689 auto* owner = current_thread->GetLockOwner();
1706 if (owner != nullptr) { 1690 if (owner != nullptr) {
@@ -1731,7 +1715,7 @@ static void SignalProcessWideKey(Core::System& system, VAddr condition_variable_
1731 1715
1732 // Retrieve a list of all threads that are waiting for this condition variable. 1716 // Retrieve a list of all threads that are waiting for this condition variable.
1733 auto& kernel = system.Kernel(); 1717 auto& kernel = system.Kernel();
1734 SchedulerLock lock(kernel); 1718 KScopedSchedulerLock lock(kernel);
1735 auto* const current_process = kernel.CurrentProcess(); 1719 auto* const current_process = kernel.CurrentProcess();
1736 std::vector<std::shared_ptr<Thread>> waiting_threads = 1720 std::vector<std::shared_ptr<Thread>> waiting_threads =
1737 current_process->GetConditionVariableThreads(condition_variable_addr); 1721 current_process->GetConditionVariableThreads(condition_variable_addr);
@@ -1993,7 +1977,7 @@ static ResultCode GetThreadCoreMask(Core::System& system, Handle thread_handle,
1993 } 1977 }
1994 1978
1995 *core = thread->GetIdealCore(); 1979 *core = thread->GetIdealCore();
1996 *mask = thread->GetAffinityMask(); 1980 *mask = thread->GetAffinityMask().GetAffinityMask();
1997 1981
1998 return RESULT_SUCCESS; 1982 return RESULT_SUCCESS;
1999} 1983}
@@ -2629,7 +2613,7 @@ void Call(Core::System& system, u32 immediate) {
2629 auto& kernel = system.Kernel(); 2613 auto& kernel = system.Kernel();
2630 kernel.EnterSVCProfile(); 2614 kernel.EnterSVCProfile();
2631 2615
2632 auto* thread = system.CurrentScheduler().GetCurrentThread(); 2616 auto* thread = kernel.CurrentScheduler()->GetCurrentThread();
2633 thread->SetContinuousOnSVC(true); 2617 thread->SetContinuousOnSVC(true);
2634 2618
2635 const FunctionDef* info = system.CurrentProcess()->Is64BitProcess() ? GetSVCInfo64(immediate) 2619 const FunctionDef* info = system.CurrentProcess()->Is64BitProcess() ? GetSVCInfo64(immediate)