diff options
Diffstat (limited to 'src/core/hle')
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 18 | ||||
| -rw-r--r-- | src/core/hle/kernel/thread.cpp | 38 | ||||
| -rw-r--r-- | src/core/hle/kernel/thread.h | 12 |
3 files changed, 31 insertions, 37 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index d7f0dcabd..dfb032b4b 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -1464,13 +1464,7 @@ static ResultCode StartThread(Core::System& system, Handle thread_handle) { | |||
| 1464 | 1464 | ||
| 1465 | ASSERT(thread->GetStatus() == ThreadStatus::Dormant); | 1465 | ASSERT(thread->GetStatus() == ThreadStatus::Dormant); |
| 1466 | 1466 | ||
| 1467 | thread->ResumeFromWait(); | 1467 | return thread->Start(); |
| 1468 | |||
| 1469 | if (thread->GetStatus() == ThreadStatus::Ready) { | ||
| 1470 | system.PrepareReschedule(thread->GetProcessorID()); | ||
| 1471 | } | ||
| 1472 | |||
| 1473 | return RESULT_SUCCESS; | ||
| 1474 | } | 1468 | } |
| 1475 | 1469 | ||
| 1476 | /// Called when a thread exits | 1470 | /// Called when a thread exits |
| @@ -1478,9 +1472,8 @@ static void ExitThread(Core::System& system) { | |||
| 1478 | LOG_DEBUG(Kernel_SVC, "called, pc=0x{:08X}", system.CurrentArmInterface().GetPC()); | 1472 | LOG_DEBUG(Kernel_SVC, "called, pc=0x{:08X}", system.CurrentArmInterface().GetPC()); |
| 1479 | 1473 | ||
| 1480 | auto* const current_thread = system.CurrentScheduler().GetCurrentThread(); | 1474 | auto* const current_thread = system.CurrentScheduler().GetCurrentThread(); |
| 1481 | current_thread->Stop(); | ||
| 1482 | system.GlobalScheduler().RemoveThread(SharedFrom(current_thread)); | 1475 | system.GlobalScheduler().RemoveThread(SharedFrom(current_thread)); |
| 1483 | system.PrepareReschedule(); | 1476 | current_thread->Stop(); |
| 1484 | } | 1477 | } |
| 1485 | 1478 | ||
| 1486 | /// Sleep the current thread | 1479 | /// Sleep the current thread |
| @@ -1500,13 +1493,13 @@ static void SleepThread(Core::System& system, s64 nanoseconds) { | |||
| 1500 | if (nanoseconds <= 0) { | 1493 | if (nanoseconds <= 0) { |
| 1501 | switch (static_cast<SleepType>(nanoseconds)) { | 1494 | switch (static_cast<SleepType>(nanoseconds)) { |
| 1502 | case SleepType::YieldWithoutLoadBalancing: | 1495 | case SleepType::YieldWithoutLoadBalancing: |
| 1503 | is_redundant = current_thread->YieldSimple(); | 1496 | current_thread->YieldSimple(); |
| 1504 | break; | 1497 | break; |
| 1505 | case SleepType::YieldWithLoadBalancing: | 1498 | case SleepType::YieldWithLoadBalancing: |
| 1506 | is_redundant = current_thread->YieldAndBalanceLoad(); | 1499 | current_thread->YieldAndBalanceLoad(); |
| 1507 | break; | 1500 | break; |
| 1508 | case SleepType::YieldAndWaitForLoadBalancing: | 1501 | case SleepType::YieldAndWaitForLoadBalancing: |
| 1509 | is_redundant = current_thread->YieldAndWaitForLoadBalancing(); | 1502 | current_thread->YieldAndWaitForLoadBalancing(); |
| 1510 | break; | 1503 | break; |
| 1511 | default: | 1504 | default: |
| 1512 | UNREACHABLE_MSG("Unimplemented sleep yield type '{:016X}'!", nanoseconds); | 1505 | UNREACHABLE_MSG("Unimplemented sleep yield type '{:016X}'!", nanoseconds); |
| @@ -1514,7 +1507,6 @@ static void SleepThread(Core::System& system, s64 nanoseconds) { | |||
| 1514 | } else { | 1507 | } else { |
| 1515 | current_thread->Sleep(nanoseconds); | 1508 | current_thread->Sleep(nanoseconds); |
| 1516 | } | 1509 | } |
| 1517 | system.PrepareReschedule(current_thread->GetProcessorID()); | ||
| 1518 | } | 1510 | } |
| 1519 | 1511 | ||
| 1520 | /// Wait process wide key atomic | 1512 | /// Wait process wide key atomic |
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 8cb3593db..d9e610272 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp | |||
| @@ -56,12 +56,6 @@ void Thread::Stop() { | |||
| 56 | SetStatus(ThreadStatus::Dead); | 56 | SetStatus(ThreadStatus::Dead); |
| 57 | Signal(); | 57 | Signal(); |
| 58 | 58 | ||
| 59 | // Clean up any dangling references in objects that this thread was waiting for | ||
| 60 | for (auto& wait_object : wait_objects) { | ||
| 61 | wait_object->RemoveWaitingThread(SharedFrom(this)); | ||
| 62 | } | ||
| 63 | wait_objects.clear(); | ||
| 64 | |||
| 65 | owner_process->UnregisterThread(this); | 59 | owner_process->UnregisterThread(this); |
| 66 | 60 | ||
| 67 | // Mark the TLS slot in the thread's page as free. | 61 | // Mark the TLS slot in the thread's page as free. |
| @@ -138,6 +132,12 @@ void Thread::OnWakeUp() { | |||
| 138 | SetStatus(ThreadStatus::Ready); | 132 | SetStatus(ThreadStatus::Ready); |
| 139 | } | 133 | } |
| 140 | 134 | ||
| 135 | ResultCode Thread::Start() { | ||
| 136 | SchedulerLock lock(kernel); | ||
| 137 | SetStatus(ThreadStatus::Ready); | ||
| 138 | return RESULT_SUCCESS; | ||
| 139 | } | ||
| 140 | |||
| 141 | void Thread::CancelWait() { | 141 | void Thread::CancelWait() { |
| 142 | if (GetSchedulingStatus() != ThreadSchedStatus::Paused) { | 142 | if (GetSchedulingStatus() != ThreadSchedStatus::Paused) { |
| 143 | is_sync_cancelled = true; | 143 | is_sync_cancelled = true; |
| @@ -188,7 +188,7 @@ ResultVal<std::shared_ptr<Thread>> Thread::Create(Core::System& system, ThreadTy | |||
| 188 | void* thread_start_parameter) { | 188 | void* thread_start_parameter) { |
| 189 | auto& kernel = system.Kernel(); | 189 | auto& kernel = system.Kernel(); |
| 190 | // Check if priority is in ranged. Lowest priority -> highest priority id. | 190 | // Check if priority is in ranged. Lowest priority -> highest priority id. |
| 191 | if (priority > THREADPRIO_LOWEST && (type_flags & THREADTYPE_IDLE == 0)) { | 191 | if (priority > THREADPRIO_LOWEST && ((type_flags & THREADTYPE_IDLE) == 0)) { |
| 192 | LOG_ERROR(Kernel_SVC, "Invalid thread priority: {}", priority); | 192 | LOG_ERROR(Kernel_SVC, "Invalid thread priority: {}", priority); |
| 193 | return ERR_INVALID_THREAD_PRIORITY; | 193 | return ERR_INVALID_THREAD_PRIORITY; |
| 194 | } | 194 | } |
| @@ -416,7 +416,7 @@ void Thread::SetActivity(ThreadActivity value) { | |||
| 416 | } | 416 | } |
| 417 | } | 417 | } |
| 418 | 418 | ||
| 419 | void Thread::Sleep(s64 nanoseconds) { | 419 | ResultCode Thread::Sleep(s64 nanoseconds) { |
| 420 | Handle event_handle{}; | 420 | Handle event_handle{}; |
| 421 | { | 421 | { |
| 422 | SchedulerLockAndSleep lock(kernel, event_handle, this, nanoseconds); | 422 | SchedulerLockAndSleep lock(kernel, event_handle, this, nanoseconds); |
| @@ -427,33 +427,31 @@ void Thread::Sleep(s64 nanoseconds) { | |||
| 427 | auto& time_manager = kernel.TimeManager(); | 427 | auto& time_manager = kernel.TimeManager(); |
| 428 | time_manager.UnscheduleTimeEvent(event_handle); | 428 | time_manager.UnscheduleTimeEvent(event_handle); |
| 429 | } | 429 | } |
| 430 | return RESULT_SUCCESS; | ||
| 430 | } | 431 | } |
| 431 | 432 | ||
| 432 | bool Thread::YieldSimple() { | 433 | ResultCode Thread::YieldSimple() { |
| 433 | bool result{}; | ||
| 434 | { | 434 | { |
| 435 | SchedulerLock lock(kernel); | 435 | SchedulerLock lock(kernel); |
| 436 | result = kernel.GlobalScheduler().YieldThread(this); | 436 | kernel.GlobalScheduler().YieldThread(this); |
| 437 | } | 437 | } |
| 438 | return result; | 438 | return RESULT_SUCCESS; |
| 439 | } | 439 | } |
| 440 | 440 | ||
| 441 | bool Thread::YieldAndBalanceLoad() { | 441 | ResultCode Thread::YieldAndBalanceLoad() { |
| 442 | bool result{}; | ||
| 443 | { | 442 | { |
| 444 | SchedulerLock lock(kernel); | 443 | SchedulerLock lock(kernel); |
| 445 | result = kernel.GlobalScheduler().YieldThreadAndBalanceLoad(this); | 444 | kernel.GlobalScheduler().YieldThreadAndBalanceLoad(this); |
| 446 | } | 445 | } |
| 447 | return result; | 446 | return RESULT_SUCCESS; |
| 448 | } | 447 | } |
| 449 | 448 | ||
| 450 | bool Thread::YieldAndWaitForLoadBalancing() { | 449 | ResultCode Thread::YieldAndWaitForLoadBalancing() { |
| 451 | bool result{}; | ||
| 452 | { | 450 | { |
| 453 | SchedulerLock lock(kernel); | 451 | SchedulerLock lock(kernel); |
| 454 | result = kernel.GlobalScheduler().YieldThreadAndWaitForLoadBalancing(this); | 452 | kernel.GlobalScheduler().YieldThreadAndWaitForLoadBalancing(this); |
| 455 | } | 453 | } |
| 456 | return result; | 454 | return RESULT_SUCCESS; |
| 457 | } | 455 | } |
| 458 | 456 | ||
| 459 | void Thread::SetSchedulingStatus(ThreadSchedStatus new_status) { | 457 | void Thread::SetSchedulingStatus(ThreadSchedStatus new_status) { |
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index 33d340b47..78a4357b0 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h | |||
| @@ -236,6 +236,8 @@ public: | |||
| 236 | 236 | ||
| 237 | void OnWakeUp(); | 237 | void OnWakeUp(); |
| 238 | 238 | ||
| 239 | ResultCode Start(); | ||
| 240 | |||
| 239 | /// Cancels a waiting operation that this thread may or may not be within. | 241 | /// Cancels a waiting operation that this thread may or may not be within. |
| 240 | /// | 242 | /// |
| 241 | /// When the thread is within a waiting state, this will set the thread's | 243 | /// When the thread is within a waiting state, this will set the thread's |
| @@ -470,16 +472,16 @@ public: | |||
| 470 | void SetActivity(ThreadActivity value); | 472 | void SetActivity(ThreadActivity value); |
| 471 | 473 | ||
| 472 | /// Sleeps this thread for the given amount of nanoseconds. | 474 | /// Sleeps this thread for the given amount of nanoseconds. |
| 473 | void Sleep(s64 nanoseconds); | 475 | ResultCode Sleep(s64 nanoseconds); |
| 474 | 476 | ||
| 475 | /// Yields this thread without rebalancing loads. | 477 | /// Yields this thread without rebalancing loads. |
| 476 | bool YieldSimple(); | 478 | ResultCode YieldSimple(); |
| 477 | 479 | ||
| 478 | /// Yields this thread and does a load rebalancing. | 480 | /// Yields this thread and does a load rebalancing. |
| 479 | bool YieldAndBalanceLoad(); | 481 | ResultCode YieldAndBalanceLoad(); |
| 480 | 482 | ||
| 481 | /// Yields this thread and if the core is left idle, loads are rebalanced | 483 | /// Yields this thread and if the core is left idle, loads are rebalanced |
| 482 | bool YieldAndWaitForLoadBalancing(); | 484 | ResultCode YieldAndWaitForLoadBalancing(); |
| 483 | 485 | ||
| 484 | void IncrementYieldCount() { | 486 | void IncrementYieldCount() { |
| 485 | yield_count++; | 487 | yield_count++; |
| @@ -603,6 +605,8 @@ private: | |||
| 603 | bool is_running = false; | 605 | bool is_running = false; |
| 604 | bool is_sync_cancelled = false; | 606 | bool is_sync_cancelled = false; |
| 605 | 607 | ||
| 608 | bool will_be_terminated{}; | ||
| 609 | |||
| 606 | std::string name; | 610 | std::string name; |
| 607 | }; | 611 | }; |
| 608 | 612 | ||