diff options
Diffstat (limited to 'src/core/hle/kernel/process.cpp')
| -rw-r--r-- | src/core/hle/kernel/process.cpp | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index c4c5199b1..f9d7c024d 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | #include "core/hle/kernel/resource_limit.h" | 22 | #include "core/hle/kernel/resource_limit.h" |
| 23 | #include "core/hle/kernel/scheduler.h" | 23 | #include "core/hle/kernel/scheduler.h" |
| 24 | #include "core/hle/kernel/thread.h" | 24 | #include "core/hle/kernel/thread.h" |
| 25 | #include "core/hle/lock.h" | ||
| 25 | #include "core/memory.h" | 26 | #include "core/memory.h" |
| 26 | #include "core/settings.h" | 27 | #include "core/settings.h" |
| 27 | 28 | ||
| @@ -30,14 +31,15 @@ namespace { | |||
| 30 | /** | 31 | /** |
| 31 | * Sets up the primary application thread | 32 | * Sets up the primary application thread |
| 32 | * | 33 | * |
| 34 | * @param system The system instance to create the main thread under. | ||
| 33 | * @param owner_process The parent process for the main thread | 35 | * @param owner_process The parent process for the main thread |
| 34 | * @param kernel The kernel instance to create the main thread under. | ||
| 35 | * @param priority The priority to give the main thread | 36 | * @param priority The priority to give the main thread |
| 36 | */ | 37 | */ |
| 37 | void SetupMainThread(Process& owner_process, KernelCore& kernel, u32 priority, VAddr stack_top) { | 38 | void SetupMainThread(Core::System& system, Process& owner_process, u32 priority, VAddr stack_top) { |
| 38 | const VAddr entry_point = owner_process.PageTable().GetCodeRegionStart(); | 39 | const VAddr entry_point = owner_process.PageTable().GetCodeRegionStart(); |
| 39 | auto thread_res = Thread::Create(kernel, "main", entry_point, priority, 0, | 40 | ThreadType type = THREADTYPE_USER; |
| 40 | owner_process.GetIdealCore(), stack_top, owner_process); | 41 | auto thread_res = Thread::Create(system, type, "main", entry_point, priority, 0, |
| 42 | owner_process.GetIdealCore(), stack_top, &owner_process); | ||
| 41 | 43 | ||
| 42 | std::shared_ptr<Thread> thread = std::move(thread_res).Unwrap(); | 44 | std::shared_ptr<Thread> thread = std::move(thread_res).Unwrap(); |
| 43 | 45 | ||
| @@ -48,8 +50,12 @@ void SetupMainThread(Process& owner_process, KernelCore& kernel, u32 priority, V | |||
| 48 | thread->GetContext32().cpu_registers[1] = thread_handle; | 50 | thread->GetContext32().cpu_registers[1] = thread_handle; |
| 49 | thread->GetContext64().cpu_registers[1] = thread_handle; | 51 | thread->GetContext64().cpu_registers[1] = thread_handle; |
| 50 | 52 | ||
| 53 | auto& kernel = system.Kernel(); | ||
| 51 | // Threads by default are dormant, wake up the main thread so it runs when the scheduler fires | 54 | // Threads by default are dormant, wake up the main thread so it runs when the scheduler fires |
| 52 | thread->ResumeFromWait(); | 55 | { |
| 56 | SchedulerLock lock{kernel}; | ||
| 57 | thread->SetStatus(ThreadStatus::Ready); | ||
| 58 | } | ||
| 53 | } | 59 | } |
| 54 | } // Anonymous namespace | 60 | } // Anonymous namespace |
| 55 | 61 | ||
| @@ -182,7 +188,6 @@ void Process::RemoveConditionVariableThread(std::shared_ptr<Thread> thread) { | |||
| 182 | } | 188 | } |
| 183 | ++it; | 189 | ++it; |
| 184 | } | 190 | } |
| 185 | UNREACHABLE(); | ||
| 186 | } | 191 | } |
| 187 | 192 | ||
| 188 | std::vector<std::shared_ptr<Thread>> Process::GetConditionVariableThreads( | 193 | std::vector<std::shared_ptr<Thread>> Process::GetConditionVariableThreads( |
| @@ -207,6 +212,7 @@ void Process::UnregisterThread(const Thread* thread) { | |||
| 207 | } | 212 | } |
| 208 | 213 | ||
| 209 | ResultCode Process::ClearSignalState() { | 214 | ResultCode Process::ClearSignalState() { |
| 215 | SchedulerLock lock(system.Kernel()); | ||
| 210 | if (status == ProcessStatus::Exited) { | 216 | if (status == ProcessStatus::Exited) { |
| 211 | LOG_ERROR(Kernel, "called on a terminated process instance."); | 217 | LOG_ERROR(Kernel, "called on a terminated process instance."); |
| 212 | return ERR_INVALID_STATE; | 218 | return ERR_INVALID_STATE; |
| @@ -294,7 +300,7 @@ void Process::Run(s32 main_thread_priority, u64 stack_size) { | |||
| 294 | 300 | ||
| 295 | ChangeStatus(ProcessStatus::Running); | 301 | ChangeStatus(ProcessStatus::Running); |
| 296 | 302 | ||
| 297 | SetupMainThread(*this, kernel, main_thread_priority, main_thread_stack_top); | 303 | SetupMainThread(system, *this, main_thread_priority, main_thread_stack_top); |
| 298 | resource_limit->Reserve(ResourceType::Threads, 1); | 304 | resource_limit->Reserve(ResourceType::Threads, 1); |
| 299 | resource_limit->Reserve(ResourceType::PhysicalMemory, main_thread_stack_size); | 305 | resource_limit->Reserve(ResourceType::PhysicalMemory, main_thread_stack_size); |
| 300 | } | 306 | } |
| @@ -340,6 +346,7 @@ static auto FindTLSPageWithAvailableSlots(std::vector<TLSPage>& tls_pages) { | |||
| 340 | } | 346 | } |
| 341 | 347 | ||
| 342 | VAddr Process::CreateTLSRegion() { | 348 | VAddr Process::CreateTLSRegion() { |
| 349 | SchedulerLock lock(system.Kernel()); | ||
| 343 | if (auto tls_page_iter{FindTLSPageWithAvailableSlots(tls_pages)}; | 350 | if (auto tls_page_iter{FindTLSPageWithAvailableSlots(tls_pages)}; |
| 344 | tls_page_iter != tls_pages.cend()) { | 351 | tls_page_iter != tls_pages.cend()) { |
| 345 | return *tls_page_iter->ReserveSlot(); | 352 | return *tls_page_iter->ReserveSlot(); |
| @@ -370,6 +377,7 @@ VAddr Process::CreateTLSRegion() { | |||
| 370 | } | 377 | } |
| 371 | 378 | ||
| 372 | void Process::FreeTLSRegion(VAddr tls_address) { | 379 | void Process::FreeTLSRegion(VAddr tls_address) { |
| 380 | SchedulerLock lock(system.Kernel()); | ||
| 373 | const VAddr aligned_address = Common::AlignDown(tls_address, Core::Memory::PAGE_SIZE); | 381 | const VAddr aligned_address = Common::AlignDown(tls_address, Core::Memory::PAGE_SIZE); |
| 374 | auto iter = | 382 | auto iter = |
| 375 | std::find_if(tls_pages.begin(), tls_pages.end(), [aligned_address](const auto& page) { | 383 | std::find_if(tls_pages.begin(), tls_pages.end(), [aligned_address](const auto& page) { |
| @@ -384,6 +392,7 @@ void Process::FreeTLSRegion(VAddr tls_address) { | |||
| 384 | } | 392 | } |
| 385 | 393 | ||
| 386 | void Process::LoadModule(CodeSet code_set, VAddr base_addr) { | 394 | void Process::LoadModule(CodeSet code_set, VAddr base_addr) { |
| 395 | std::lock_guard lock{HLE::g_hle_lock}; | ||
| 387 | const auto ReprotectSegment = [&](const CodeSet::Segment& segment, | 396 | const auto ReprotectSegment = [&](const CodeSet::Segment& segment, |
| 388 | Memory::MemoryPermission permission) { | 397 | Memory::MemoryPermission permission) { |
| 389 | page_table->SetCodeMemoryPermission(segment.addr + base_addr, segment.size, permission); | 398 | page_table->SetCodeMemoryPermission(segment.addr + base_addr, segment.size, permission); |