diff options
| author | 2018-12-30 20:32:41 -0500 | |
|---|---|---|
| committer | 2018-12-30 20:32:41 -0500 | |
| commit | e5dfbe22ee458dc818e5e56daa7f1a43e6ed7205 (patch) | |
| tree | d12208284c7f3bff0d24ba5750019307eddccefe /src | |
| parent | Merge pull request #1847 from ogniK5377/backtrace-break (diff) | |
| parent | kernel/process: Start the main thread using the specified ideal core (diff) | |
| download | yuzu-e5dfbe22ee458dc818e5e56daa7f1a43e6ed7205.tar.gz yuzu-e5dfbe22ee458dc818e5e56daa7f1a43e6ed7205.tar.xz yuzu-e5dfbe22ee458dc818e5e56daa7f1a43e6ed7205.zip | |
Merge pull request #1956 from lioncash/process-thread
kernel/process: Start the main thread using the specified ideal core
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/kernel/process.cpp | 33 | ||||
| -rw-r--r-- | src/core/hle/kernel/process.h | 10 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 18 | ||||
| -rw-r--r-- | src/core/hle/kernel/thread.cpp | 24 | ||||
| -rw-r--r-- | src/core/hle/kernel/thread.h | 23 | ||||
| -rw-r--r-- | src/yuzu/debugger/wait_tree.cpp | 4 |
6 files changed, 53 insertions, 59 deletions
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index 06a673b9b..c5aa19afa 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp | |||
| @@ -20,6 +20,35 @@ | |||
| 20 | #include "core/settings.h" | 20 | #include "core/settings.h" |
| 21 | 21 | ||
| 22 | namespace Kernel { | 22 | namespace Kernel { |
| 23 | namespace { | ||
| 24 | /** | ||
| 25 | * Sets up the primary application thread | ||
| 26 | * | ||
| 27 | * @param owner_process The parent process for the main thread | ||
| 28 | * @param kernel The kernel instance to create the main thread under. | ||
| 29 | * @param entry_point The address at which the thread should start execution | ||
| 30 | * @param priority The priority to give the main thread | ||
| 31 | */ | ||
| 32 | void SetupMainThread(Process& owner_process, KernelCore& kernel, VAddr entry_point, u32 priority) { | ||
| 33 | // Setup page table so we can write to memory | ||
| 34 | SetCurrentPageTable(&owner_process.VMManager().page_table); | ||
| 35 | |||
| 36 | // Initialize new "main" thread | ||
| 37 | const VAddr stack_top = owner_process.VMManager().GetTLSIORegionEndAddress(); | ||
| 38 | auto thread_res = Thread::Create(kernel, "main", entry_point, priority, 0, | ||
| 39 | owner_process.GetIdealCore(), stack_top, owner_process); | ||
| 40 | |||
| 41 | SharedPtr<Thread> thread = std::move(thread_res).Unwrap(); | ||
| 42 | |||
| 43 | // Register 1 must be a handle to the main thread | ||
| 44 | const Handle guest_handle = owner_process.GetHandleTable().Create(thread).Unwrap(); | ||
| 45 | thread->SetGuestHandle(guest_handle); | ||
| 46 | thread->GetContext().cpu_registers[1] = guest_handle; | ||
| 47 | |||
| 48 | // Threads by default are dormant, wake up the main thread so it runs when the scheduler fires | ||
| 49 | thread->ResumeFromWait(); | ||
| 50 | } | ||
| 51 | } // Anonymous namespace | ||
| 23 | 52 | ||
| 24 | CodeSet::CodeSet() = default; | 53 | CodeSet::CodeSet() = default; |
| 25 | CodeSet::~CodeSet() = default; | 54 | CodeSet::~CodeSet() = default; |
| @@ -64,7 +93,7 @@ ResultCode Process::ClearSignalState() { | |||
| 64 | 93 | ||
| 65 | ResultCode Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata) { | 94 | ResultCode Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata) { |
| 66 | program_id = metadata.GetTitleID(); | 95 | program_id = metadata.GetTitleID(); |
| 67 | ideal_processor = metadata.GetMainThreadCore(); | 96 | ideal_core = metadata.GetMainThreadCore(); |
| 68 | is_64bit_process = metadata.Is64BitProgram(); | 97 | is_64bit_process = metadata.Is64BitProgram(); |
| 69 | 98 | ||
| 70 | vm_manager.Reset(metadata.GetAddressSpaceType()); | 99 | vm_manager.Reset(metadata.GetAddressSpaceType()); |
| @@ -86,7 +115,7 @@ void Process::Run(VAddr entry_point, s32 main_thread_priority, u32 stack_size) { | |||
| 86 | vm_manager.LogLayout(); | 115 | vm_manager.LogLayout(); |
| 87 | ChangeStatus(ProcessStatus::Running); | 116 | ChangeStatus(ProcessStatus::Running); |
| 88 | 117 | ||
| 89 | Kernel::SetupMainThread(kernel, entry_point, main_thread_priority, *this); | 118 | SetupMainThread(*this, kernel, entry_point, main_thread_priority); |
| 90 | } | 119 | } |
| 91 | 120 | ||
| 92 | void Process::PrepareForTermination() { | 121 | void Process::PrepareForTermination() { |
diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index ac6956266..450dc6eeb 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h | |||
| @@ -168,9 +168,9 @@ public: | |||
| 168 | /// Gets the resource limit descriptor for this process | 168 | /// Gets the resource limit descriptor for this process |
| 169 | SharedPtr<ResourceLimit> GetResourceLimit() const; | 169 | SharedPtr<ResourceLimit> GetResourceLimit() const; |
| 170 | 170 | ||
| 171 | /// Gets the default CPU ID for this process | 171 | /// Gets the ideal CPU core ID for this process |
| 172 | u8 GetDefaultProcessorID() const { | 172 | u8 GetIdealCore() const { |
| 173 | return ideal_processor; | 173 | return ideal_core; |
| 174 | } | 174 | } |
| 175 | 175 | ||
| 176 | /// Gets the bitmask of allowed CPUs that this process' threads can run on. | 176 | /// Gets the bitmask of allowed CPUs that this process' threads can run on. |
| @@ -280,8 +280,8 @@ private: | |||
| 280 | /// Resource limit descriptor for this process | 280 | /// Resource limit descriptor for this process |
| 281 | SharedPtr<ResourceLimit> resource_limit; | 281 | SharedPtr<ResourceLimit> resource_limit; |
| 282 | 282 | ||
| 283 | /// The default CPU for this process, threads are scheduled on this cpu by default. | 283 | /// The ideal CPU core for this process, threads are scheduled on this core by default. |
| 284 | u8 ideal_processor = 0; | 284 | u8 ideal_core = 0; |
| 285 | u32 is_virtual_address_memory_enabled = 0; | 285 | u32 is_virtual_address_memory_enabled = 0; |
| 286 | 286 | ||
| 287 | /// The Thread Local Storage area is allocated as processes create threads, | 287 | /// The Thread Local Storage area is allocated as processes create threads, |
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 5fac831ee..660e6f577 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -1227,10 +1227,10 @@ static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, V | |||
| 1227 | 1227 | ||
| 1228 | auto* const current_process = Core::CurrentProcess(); | 1228 | auto* const current_process = Core::CurrentProcess(); |
| 1229 | 1229 | ||
| 1230 | if (processor_id == THREADPROCESSORID_DEFAULT) { | 1230 | if (processor_id == THREADPROCESSORID_IDEAL) { |
| 1231 | // Set the target CPU to the one specified in the process' exheader. | 1231 | // Set the target CPU to the one specified by the process. |
| 1232 | processor_id = current_process->GetDefaultProcessorID(); | 1232 | processor_id = current_process->GetIdealCore(); |
| 1233 | ASSERT(processor_id != THREADPROCESSORID_DEFAULT); | 1233 | ASSERT(processor_id != THREADPROCESSORID_IDEAL); |
| 1234 | } | 1234 | } |
| 1235 | 1235 | ||
| 1236 | switch (processor_id) { | 1236 | switch (processor_id) { |
| @@ -1639,13 +1639,13 @@ static ResultCode SetThreadCoreMask(Handle thread_handle, u32 core, u64 mask) { | |||
| 1639 | return ERR_INVALID_HANDLE; | 1639 | return ERR_INVALID_HANDLE; |
| 1640 | } | 1640 | } |
| 1641 | 1641 | ||
| 1642 | if (core == static_cast<u32>(THREADPROCESSORID_DEFAULT)) { | 1642 | if (core == static_cast<u32>(THREADPROCESSORID_IDEAL)) { |
| 1643 | const u8 default_processor_id = thread->GetOwnerProcess()->GetDefaultProcessorID(); | 1643 | const u8 ideal_cpu_core = thread->GetOwnerProcess()->GetIdealCore(); |
| 1644 | 1644 | ||
| 1645 | ASSERT(default_processor_id != static_cast<u8>(THREADPROCESSORID_DEFAULT)); | 1645 | ASSERT(ideal_cpu_core != static_cast<u8>(THREADPROCESSORID_IDEAL)); |
| 1646 | 1646 | ||
| 1647 | // Set the target CPU to the one specified in the process' exheader. | 1647 | // Set the target CPU to the ideal core specified by the process. |
| 1648 | core = default_processor_id; | 1648 | core = ideal_cpu_core; |
| 1649 | mask = 1ULL << core; | 1649 | mask = 1ULL << core; |
| 1650 | } | 1650 | } |
| 1651 | 1651 | ||
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 434655638..d3984dfc4 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp | |||
| @@ -12,7 +12,6 @@ | |||
| 12 | #include "common/assert.h" | 12 | #include "common/assert.h" |
| 13 | #include "common/common_types.h" | 13 | #include "common/common_types.h" |
| 14 | #include "common/logging/log.h" | 14 | #include "common/logging/log.h" |
| 15 | #include "common/math_util.h" | ||
| 16 | #include "common/thread_queue_list.h" | 15 | #include "common/thread_queue_list.h" |
| 17 | #include "core/arm/arm_interface.h" | 16 | #include "core/arm/arm_interface.h" |
| 18 | #include "core/core.h" | 17 | #include "core/core.h" |
| @@ -232,29 +231,6 @@ void Thread::BoostPriority(u32 priority) { | |||
| 232 | current_priority = priority; | 231 | current_priority = priority; |
| 233 | } | 232 | } |
| 234 | 233 | ||
| 235 | SharedPtr<Thread> SetupMainThread(KernelCore& kernel, VAddr entry_point, u32 priority, | ||
| 236 | Process& owner_process) { | ||
| 237 | // Setup page table so we can write to memory | ||
| 238 | SetCurrentPageTable(&owner_process.VMManager().page_table); | ||
| 239 | |||
| 240 | // Initialize new "main" thread | ||
| 241 | const VAddr stack_top = owner_process.VMManager().GetTLSIORegionEndAddress(); | ||
| 242 | auto thread_res = Thread::Create(kernel, "main", entry_point, priority, 0, THREADPROCESSORID_0, | ||
| 243 | stack_top, owner_process); | ||
| 244 | |||
| 245 | SharedPtr<Thread> thread = std::move(thread_res).Unwrap(); | ||
| 246 | |||
| 247 | // Register 1 must be a handle to the main thread | ||
| 248 | const Handle guest_handle = owner_process.GetHandleTable().Create(thread).Unwrap(); | ||
| 249 | thread->SetGuestHandle(guest_handle); | ||
| 250 | thread->GetContext().cpu_registers[1] = guest_handle; | ||
| 251 | |||
| 252 | // Threads by default are dormant, wake up the main thread so it runs when the scheduler fires | ||
| 253 | thread->ResumeFromWait(); | ||
| 254 | |||
| 255 | return thread; | ||
| 256 | } | ||
| 257 | |||
| 258 | void Thread::SetWaitSynchronizationResult(ResultCode result) { | 234 | void Thread::SetWaitSynchronizationResult(ResultCode result) { |
| 259 | context.cpu_registers[0] = result.raw; | 235 | context.cpu_registers[0] = result.raw; |
| 260 | } | 236 | } |
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index fe5398d56..c48b21aba 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h | |||
| @@ -30,12 +30,12 @@ enum ThreadPriority : u32 { | |||
| 30 | }; | 30 | }; |
| 31 | 31 | ||
| 32 | enum ThreadProcessorId : s32 { | 32 | enum ThreadProcessorId : s32 { |
| 33 | THREADPROCESSORID_DEFAULT = -2, ///< Run thread on default core specified by exheader | 33 | THREADPROCESSORID_IDEAL = -2, ///< Run thread on the ideal core specified by the process. |
| 34 | THREADPROCESSORID_0 = 0, ///< Run thread on core 0 | 34 | THREADPROCESSORID_0 = 0, ///< Run thread on core 0 |
| 35 | THREADPROCESSORID_1 = 1, ///< Run thread on core 1 | 35 | THREADPROCESSORID_1 = 1, ///< Run thread on core 1 |
| 36 | THREADPROCESSORID_2 = 2, ///< Run thread on core 2 | 36 | THREADPROCESSORID_2 = 2, ///< Run thread on core 2 |
| 37 | THREADPROCESSORID_3 = 3, ///< Run thread on core 3 | 37 | THREADPROCESSORID_3 = 3, ///< Run thread on core 3 |
| 38 | THREADPROCESSORID_MAX = 4, ///< Processor ID must be less than this | 38 | THREADPROCESSORID_MAX = 4, ///< Processor ID must be less than this |
| 39 | 39 | ||
| 40 | /// Allowed CPU mask | 40 | /// Allowed CPU mask |
| 41 | THREADPROCESSORID_DEFAULT_MASK = (1 << THREADPROCESSORID_0) | (1 << THREADPROCESSORID_1) | | 41 | THREADPROCESSORID_DEFAULT_MASK = (1 << THREADPROCESSORID_0) | (1 << THREADPROCESSORID_1) | |
| @@ -456,17 +456,6 @@ private: | |||
| 456 | }; | 456 | }; |
| 457 | 457 | ||
| 458 | /** | 458 | /** |
| 459 | * Sets up the primary application thread | ||
| 460 | * @param kernel The kernel instance to create the main thread under. | ||
| 461 | * @param entry_point The address at which the thread should start execution | ||
| 462 | * @param priority The priority to give the main thread | ||
| 463 | * @param owner_process The parent process for the main thread | ||
| 464 | * @return A shared pointer to the main thread | ||
| 465 | */ | ||
| 466 | SharedPtr<Thread> SetupMainThread(KernelCore& kernel, VAddr entry_point, u32 priority, | ||
| 467 | Process& owner_process); | ||
| 468 | |||
| 469 | /** | ||
| 470 | * Gets the current thread | 459 | * Gets the current thread |
| 471 | */ | 460 | */ |
| 472 | Thread* GetCurrentThread(); | 461 | Thread* GetCurrentThread(); |
diff --git a/src/yuzu/debugger/wait_tree.cpp b/src/yuzu/debugger/wait_tree.cpp index 1adf6e330..df6eeb9a6 100644 --- a/src/yuzu/debugger/wait_tree.cpp +++ b/src/yuzu/debugger/wait_tree.cpp | |||
| @@ -293,8 +293,8 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeThread::GetChildren() const { | |||
| 293 | 293 | ||
| 294 | QString processor; | 294 | QString processor; |
| 295 | switch (thread.GetProcessorID()) { | 295 | switch (thread.GetProcessorID()) { |
| 296 | case Kernel::ThreadProcessorId::THREADPROCESSORID_DEFAULT: | 296 | case Kernel::ThreadProcessorId::THREADPROCESSORID_IDEAL: |
| 297 | processor = tr("default"); | 297 | processor = tr("ideal"); |
| 298 | break; | 298 | break; |
| 299 | case Kernel::ThreadProcessorId::THREADPROCESSORID_0: | 299 | case Kernel::ThreadProcessorId::THREADPROCESSORID_0: |
| 300 | case Kernel::ThreadProcessorId::THREADPROCESSORID_1: | 300 | case Kernel::ThreadProcessorId::THREADPROCESSORID_1: |