diff options
| author | 2019-05-19 13:59:52 -0400 | |
|---|---|---|
| committer | 2019-05-19 13:59:52 -0400 | |
| commit | 13dda1d8ed4716f844706c52c8b4832b9b1ad8ce (patch) | |
| tree | 2a7f731518639a5d0e0c87a7c72d105bf78e16ea /src/core/hle/kernel/svc.cpp | |
| parent | Merge pull request #2491 from FernandoS27/dma-fix (diff) | |
| parent | kernel/svc: Make svcCreateThread/svcStartThread/svcSleepThread/svcExitThread ... (diff) | |
| download | yuzu-13dda1d8ed4716f844706c52c8b4832b9b1ad8ce.tar.gz yuzu-13dda1d8ed4716f844706c52c8b4832b9b1ad8ce.tar.xz yuzu-13dda1d8ed4716f844706c52c8b4832b9b1ad8ce.zip | |
Merge pull request #2410 from lioncash/affinity
kernel/svc: Reorganize and fix up the initial handling of svcSetThreadCoreMask()
Diffstat (limited to 'src/core/hle/kernel/svc.cpp')
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 79 |
1 files changed, 43 insertions, 36 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index c23106299..5a5851f66 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -1342,7 +1342,7 @@ static void ExitProcess(Core::System& system) { | |||
| 1342 | /// Creates a new thread | 1342 | /// Creates a new thread |
| 1343 | static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr entry_point, u64 arg, | 1343 | static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr entry_point, u64 arg, |
| 1344 | VAddr stack_top, u32 priority, s32 processor_id) { | 1344 | VAddr stack_top, u32 priority, s32 processor_id) { |
| 1345 | LOG_TRACE(Kernel_SVC, | 1345 | LOG_DEBUG(Kernel_SVC, |
| 1346 | "called entrypoint=0x{:08X}, arg=0x{:08X}, stacktop=0x{:08X}, " | 1346 | "called entrypoint=0x{:08X}, arg=0x{:08X}, stacktop=0x{:08X}, " |
| 1347 | "threadpriority=0x{:08X}, processorid=0x{:08X} : created handle=0x{:08X}", | 1347 | "threadpriority=0x{:08X}, processorid=0x{:08X} : created handle=0x{:08X}", |
| 1348 | entry_point, arg, stack_top, priority, processor_id, *out_handle); | 1348 | entry_point, arg, stack_top, priority, processor_id, *out_handle); |
| @@ -1402,7 +1402,7 @@ static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr e | |||
| 1402 | 1402 | ||
| 1403 | /// Starts the thread for the provided handle | 1403 | /// Starts the thread for the provided handle |
| 1404 | static ResultCode StartThread(Core::System& system, Handle thread_handle) { | 1404 | static ResultCode StartThread(Core::System& system, Handle thread_handle) { |
| 1405 | LOG_TRACE(Kernel_SVC, "called thread=0x{:08X}", thread_handle); | 1405 | LOG_DEBUG(Kernel_SVC, "called thread=0x{:08X}", thread_handle); |
| 1406 | 1406 | ||
| 1407 | const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); | 1407 | const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); |
| 1408 | const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle); | 1408 | const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle); |
| @@ -1425,7 +1425,7 @@ static ResultCode StartThread(Core::System& system, Handle thread_handle) { | |||
| 1425 | 1425 | ||
| 1426 | /// Called when a thread exits | 1426 | /// Called when a thread exits |
| 1427 | static void ExitThread(Core::System& system) { | 1427 | static void ExitThread(Core::System& system) { |
| 1428 | LOG_TRACE(Kernel_SVC, "called, pc=0x{:08X}", system.CurrentArmInterface().GetPC()); | 1428 | LOG_DEBUG(Kernel_SVC, "called, pc=0x{:08X}", system.CurrentArmInterface().GetPC()); |
| 1429 | 1429 | ||
| 1430 | auto* const current_thread = system.CurrentScheduler().GetCurrentThread(); | 1430 | auto* const current_thread = system.CurrentScheduler().GetCurrentThread(); |
| 1431 | current_thread->Stop(); | 1431 | current_thread->Stop(); |
| @@ -1435,7 +1435,7 @@ static void ExitThread(Core::System& system) { | |||
| 1435 | 1435 | ||
| 1436 | /// Sleep the current thread | 1436 | /// Sleep the current thread |
| 1437 | static void SleepThread(Core::System& system, s64 nanoseconds) { | 1437 | static void SleepThread(Core::System& system, s64 nanoseconds) { |
| 1438 | LOG_TRACE(Kernel_SVC, "called nanoseconds={}", nanoseconds); | 1438 | LOG_DEBUG(Kernel_SVC, "called nanoseconds={}", nanoseconds); |
| 1439 | 1439 | ||
| 1440 | enum class SleepType : s64 { | 1440 | enum class SleepType : s64 { |
| 1441 | YieldWithoutLoadBalancing = 0, | 1441 | YieldWithoutLoadBalancing = 0, |
| @@ -1880,52 +1880,59 @@ static ResultCode GetThreadCoreMask(Core::System& system, Handle thread_handle, | |||
| 1880 | } | 1880 | } |
| 1881 | 1881 | ||
| 1882 | static ResultCode SetThreadCoreMask(Core::System& system, Handle thread_handle, u32 core, | 1882 | static ResultCode SetThreadCoreMask(Core::System& system, Handle thread_handle, u32 core, |
| 1883 | u64 mask) { | 1883 | u64 affinity_mask) { |
| 1884 | LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, mask=0x{:016X}, core=0x{:X}", thread_handle, | 1884 | LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, core=0x{:X}, affinity_mask=0x{:016X}", |
| 1885 | mask, core); | 1885 | thread_handle, core, affinity_mask); |
| 1886 | 1886 | ||
| 1887 | const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); | 1887 | const auto* const current_process = system.Kernel().CurrentProcess(); |
| 1888 | const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle); | ||
| 1889 | if (!thread) { | ||
| 1890 | LOG_ERROR(Kernel_SVC, "Thread handle does not exist, thread_handle=0x{:08X}", | ||
| 1891 | thread_handle); | ||
| 1892 | return ERR_INVALID_HANDLE; | ||
| 1893 | } | ||
| 1894 | 1888 | ||
| 1895 | if (core == static_cast<u32>(THREADPROCESSORID_IDEAL)) { | 1889 | if (core == static_cast<u32>(THREADPROCESSORID_IDEAL)) { |
| 1896 | const u8 ideal_cpu_core = thread->GetOwnerProcess()->GetIdealCore(); | 1890 | const u8 ideal_cpu_core = current_process->GetIdealCore(); |
| 1897 | 1891 | ||
| 1898 | ASSERT(ideal_cpu_core != static_cast<u8>(THREADPROCESSORID_IDEAL)); | 1892 | ASSERT(ideal_cpu_core != static_cast<u8>(THREADPROCESSORID_IDEAL)); |
| 1899 | 1893 | ||
| 1900 | // Set the target CPU to the ideal core specified by the process. | 1894 | // Set the target CPU to the ideal core specified by the process. |
| 1901 | core = ideal_cpu_core; | 1895 | core = ideal_cpu_core; |
| 1902 | mask = 1ULL << core; | 1896 | affinity_mask = 1ULL << core; |
| 1903 | } | 1897 | } else { |
| 1904 | 1898 | const u64 core_mask = current_process->GetCoreMask(); | |
| 1905 | if (mask == 0) { | 1899 | |
| 1906 | LOG_ERROR(Kernel_SVC, "Mask is 0"); | 1900 | if ((core_mask | affinity_mask) != core_mask) { |
| 1907 | return ERR_INVALID_COMBINATION; | 1901 | LOG_ERROR( |
| 1908 | } | 1902 | Kernel_SVC, |
| 1903 | "Invalid processor ID specified (core_mask=0x{:08X}, affinity_mask=0x{:016X})", | ||
| 1904 | core_mask, affinity_mask); | ||
| 1905 | return ERR_INVALID_PROCESSOR_ID; | ||
| 1906 | } | ||
| 1909 | 1907 | ||
| 1910 | /// This value is used to only change the affinity mask without changing the current ideal core. | 1908 | if (affinity_mask == 0) { |
| 1911 | static constexpr u32 OnlyChangeMask = static_cast<u32>(-3); | 1909 | LOG_ERROR(Kernel_SVC, "Specfified affinity mask is zero."); |
| 1910 | return ERR_INVALID_COMBINATION; | ||
| 1911 | } | ||
| 1912 | 1912 | ||
| 1913 | if (core == OnlyChangeMask) { | 1913 | if (core < Core::NUM_CPU_CORES) { |
| 1914 | core = thread->GetIdealCore(); | 1914 | if ((affinity_mask & (1ULL << core)) == 0) { |
| 1915 | } else if (core >= Core::NUM_CPU_CORES && core != static_cast<u32>(-1)) { | 1915 | LOG_ERROR(Kernel_SVC, |
| 1916 | LOG_ERROR(Kernel_SVC, "Invalid core specified, got {}", core); | 1916 | "Core is not enabled for the current mask, core={}, mask={:016X}", core, |
| 1917 | return ERR_INVALID_PROCESSOR_ID; | 1917 | affinity_mask); |
| 1918 | return ERR_INVALID_COMBINATION; | ||
| 1919 | } | ||
| 1920 | } else if (core != static_cast<u32>(THREADPROCESSORID_DONT_CARE) && | ||
| 1921 | core != static_cast<u32>(THREADPROCESSORID_DONT_UPDATE)) { | ||
| 1922 | LOG_ERROR(Kernel_SVC, "Invalid processor ID specified (core={}).", core); | ||
| 1923 | return ERR_INVALID_PROCESSOR_ID; | ||
| 1924 | } | ||
| 1918 | } | 1925 | } |
| 1919 | 1926 | ||
| 1920 | // Error out if the input core isn't enabled in the input mask. | 1927 | const auto& handle_table = current_process->GetHandleTable(); |
| 1921 | if (core < Core::NUM_CPU_CORES && (mask & (1ull << core)) == 0) { | 1928 | const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle); |
| 1922 | LOG_ERROR(Kernel_SVC, "Core is not enabled for the current mask, core={}, mask={:016X}", | 1929 | if (!thread) { |
| 1923 | core, mask); | 1930 | LOG_ERROR(Kernel_SVC, "Thread handle does not exist, thread_handle=0x{:08X}", |
| 1924 | return ERR_INVALID_COMBINATION; | 1931 | thread_handle); |
| 1932 | return ERR_INVALID_HANDLE; | ||
| 1925 | } | 1933 | } |
| 1926 | 1934 | ||
| 1927 | thread->ChangeCore(core, mask); | 1935 | thread->ChangeCore(core, affinity_mask); |
| 1928 | |||
| 1929 | return RESULT_SUCCESS; | 1936 | return RESULT_SUCCESS; |
| 1930 | } | 1937 | } |
| 1931 | 1938 | ||