Kaynağa Gözat

SVC: Correct CreateThread, StartThread, ExitThread, SleepThread.

Fernando Sahmkow 6 yıl önce
ebeveyn
işleme
49ba563995

+ 5 - 13
src/core/hle/kernel/svc.cpp

@@ -1464,13 +1464,7 @@ static ResultCode StartThread(Core::System& system, Handle thread_handle) {
 
 
     ASSERT(thread->GetStatus() == ThreadStatus::Dormant);
     ASSERT(thread->GetStatus() == ThreadStatus::Dormant);
 
 
-    thread->ResumeFromWait();
-
-    if (thread->GetStatus() == ThreadStatus::Ready) {
-        system.PrepareReschedule(thread->GetProcessorID());
-    }
-
-    return RESULT_SUCCESS;
+    return thread->Start();
 }
 }
 
 
 /// Called when a thread exits
 /// Called when a thread exits
@@ -1478,9 +1472,8 @@ static void ExitThread(Core::System& system) {
     LOG_DEBUG(Kernel_SVC, "called, pc=0x{:08X}", system.CurrentArmInterface().GetPC());
     LOG_DEBUG(Kernel_SVC, "called, pc=0x{:08X}", system.CurrentArmInterface().GetPC());
 
 
     auto* const current_thread = system.CurrentScheduler().GetCurrentThread();
     auto* const current_thread = system.CurrentScheduler().GetCurrentThread();
-    current_thread->Stop();
     system.GlobalScheduler().RemoveThread(SharedFrom(current_thread));
     system.GlobalScheduler().RemoveThread(SharedFrom(current_thread));
-    system.PrepareReschedule();
+    current_thread->Stop();
 }
 }
 
 
 /// Sleep the current thread
 /// Sleep the current thread
@@ -1500,13 +1493,13 @@ static void SleepThread(Core::System& system, s64 nanoseconds) {
     if (nanoseconds <= 0) {
     if (nanoseconds <= 0) {
         switch (static_cast<SleepType>(nanoseconds)) {
         switch (static_cast<SleepType>(nanoseconds)) {
         case SleepType::YieldWithoutLoadBalancing:
         case SleepType::YieldWithoutLoadBalancing:
-            is_redundant = current_thread->YieldSimple();
+            current_thread->YieldSimple();
             break;
             break;
         case SleepType::YieldWithLoadBalancing:
         case SleepType::YieldWithLoadBalancing:
-            is_redundant = current_thread->YieldAndBalanceLoad();
+            current_thread->YieldAndBalanceLoad();
             break;
             break;
         case SleepType::YieldAndWaitForLoadBalancing:
         case SleepType::YieldAndWaitForLoadBalancing:
-            is_redundant = current_thread->YieldAndWaitForLoadBalancing();
+            current_thread->YieldAndWaitForLoadBalancing();
             break;
             break;
         default:
         default:
             UNREACHABLE_MSG("Unimplemented sleep yield type '{:016X}'!", nanoseconds);
             UNREACHABLE_MSG("Unimplemented sleep yield type '{:016X}'!", nanoseconds);
@@ -1514,7 +1507,6 @@ static void SleepThread(Core::System& system, s64 nanoseconds) {
     } else {
     } else {
         current_thread->Sleep(nanoseconds);
         current_thread->Sleep(nanoseconds);
     }
     }
-    system.PrepareReschedule(current_thread->GetProcessorID());
 }
 }
 
 
 /// Wait process wide key atomic
 /// Wait process wide key atomic

+ 18 - 20
src/core/hle/kernel/thread.cpp

@@ -56,12 +56,6 @@ void Thread::Stop() {
     SetStatus(ThreadStatus::Dead);
     SetStatus(ThreadStatus::Dead);
     Signal();
     Signal();
 
 
-    // Clean up any dangling references in objects that this thread was waiting for
-    for (auto& wait_object : wait_objects) {
-        wait_object->RemoveWaitingThread(SharedFrom(this));
-    }
-    wait_objects.clear();
-
     owner_process->UnregisterThread(this);
     owner_process->UnregisterThread(this);
 
 
     // Mark the TLS slot in the thread's page as free.
     // Mark the TLS slot in the thread's page as free.
@@ -138,6 +132,12 @@ void Thread::OnWakeUp() {
     SetStatus(ThreadStatus::Ready);
     SetStatus(ThreadStatus::Ready);
 }
 }
 
 
+ResultCode Thread::Start() {
+    SchedulerLock lock(kernel);
+    SetStatus(ThreadStatus::Ready);
+    return RESULT_SUCCESS;
+}
+
 void Thread::CancelWait() {
 void Thread::CancelWait() {
     if (GetSchedulingStatus() != ThreadSchedStatus::Paused) {
     if (GetSchedulingStatus() != ThreadSchedStatus::Paused) {
         is_sync_cancelled = true;
         is_sync_cancelled = true;
@@ -188,7 +188,7 @@ ResultVal<std::shared_ptr<Thread>> Thread::Create(Core::System& system, ThreadTy
                                                   void* thread_start_parameter) {
                                                   void* thread_start_parameter) {
     auto& kernel = system.Kernel();
     auto& kernel = system.Kernel();
     // Check if priority is in ranged. Lowest priority -> highest priority id.
     // Check if priority is in ranged. Lowest priority -> highest priority id.
-    if (priority > THREADPRIO_LOWEST && (type_flags & THREADTYPE_IDLE == 0)) {
+    if (priority > THREADPRIO_LOWEST && ((type_flags & THREADTYPE_IDLE) == 0)) {
         LOG_ERROR(Kernel_SVC, "Invalid thread priority: {}", priority);
         LOG_ERROR(Kernel_SVC, "Invalid thread priority: {}", priority);
         return ERR_INVALID_THREAD_PRIORITY;
         return ERR_INVALID_THREAD_PRIORITY;
     }
     }
@@ -416,7 +416,7 @@ void Thread::SetActivity(ThreadActivity value) {
     }
     }
 }
 }
 
 
-void Thread::Sleep(s64 nanoseconds) {
+ResultCode Thread::Sleep(s64 nanoseconds) {
     Handle event_handle{};
     Handle event_handle{};
     {
     {
         SchedulerLockAndSleep lock(kernel, event_handle, this, nanoseconds);
         SchedulerLockAndSleep lock(kernel, event_handle, this, nanoseconds);
@@ -427,33 +427,31 @@ void Thread::Sleep(s64 nanoseconds) {
         auto& time_manager = kernel.TimeManager();
         auto& time_manager = kernel.TimeManager();
         time_manager.UnscheduleTimeEvent(event_handle);
         time_manager.UnscheduleTimeEvent(event_handle);
     }
     }
+    return RESULT_SUCCESS;
 }
 }
 
 
-bool Thread::YieldSimple() {
-    bool result{};
+ResultCode Thread::YieldSimple() {
     {
     {
         SchedulerLock lock(kernel);
         SchedulerLock lock(kernel);
-        result = kernel.GlobalScheduler().YieldThread(this);
+        kernel.GlobalScheduler().YieldThread(this);
     }
     }
-    return result;
+    return RESULT_SUCCESS;
 }
 }
 
 
-bool Thread::YieldAndBalanceLoad() {
-    bool result{};
+ResultCode Thread::YieldAndBalanceLoad() {
     {
     {
         SchedulerLock lock(kernel);
         SchedulerLock lock(kernel);
-        result = kernel.GlobalScheduler().YieldThreadAndBalanceLoad(this);
+        kernel.GlobalScheduler().YieldThreadAndBalanceLoad(this);
     }
     }
-    return result;
+    return RESULT_SUCCESS;
 }
 }
 
 
-bool Thread::YieldAndWaitForLoadBalancing() {
-    bool result{};
+ResultCode Thread::YieldAndWaitForLoadBalancing() {
     {
     {
         SchedulerLock lock(kernel);
         SchedulerLock lock(kernel);
-        result = kernel.GlobalScheduler().YieldThreadAndWaitForLoadBalancing(this);
+        kernel.GlobalScheduler().YieldThreadAndWaitForLoadBalancing(this);
     }
     }
-    return result;
+    return RESULT_SUCCESS;
 }
 }
 
 
 void Thread::SetSchedulingStatus(ThreadSchedStatus new_status) {
 void Thread::SetSchedulingStatus(ThreadSchedStatus new_status) {

+ 8 - 4
src/core/hle/kernel/thread.h

@@ -236,6 +236,8 @@ public:
 
 
     void OnWakeUp();
     void OnWakeUp();
 
 
+    ResultCode Start();
+
     /// Cancels a waiting operation that this thread may or may not be within.
     /// Cancels a waiting operation that this thread may or may not be within.
     ///
     ///
     /// When the thread is within a waiting state, this will set the thread's
     /// When the thread is within a waiting state, this will set the thread's
@@ -470,16 +472,16 @@ public:
     void SetActivity(ThreadActivity value);
     void SetActivity(ThreadActivity value);
 
 
     /// Sleeps this thread for the given amount of nanoseconds.
     /// Sleeps this thread for the given amount of nanoseconds.
-    void Sleep(s64 nanoseconds);
+    ResultCode Sleep(s64 nanoseconds);
 
 
     /// Yields this thread without rebalancing loads.
     /// Yields this thread without rebalancing loads.
-    bool YieldSimple();
+    ResultCode YieldSimple();
 
 
     /// Yields this thread and does a load rebalancing.
     /// Yields this thread and does a load rebalancing.
-    bool YieldAndBalanceLoad();
+    ResultCode YieldAndBalanceLoad();
 
 
     /// Yields this thread and if the core is left idle, loads are rebalanced
     /// Yields this thread and if the core is left idle, loads are rebalanced
-    bool YieldAndWaitForLoadBalancing();
+    ResultCode YieldAndWaitForLoadBalancing();
 
 
     void IncrementYieldCount() {
     void IncrementYieldCount() {
         yield_count++;
         yield_count++;
@@ -603,6 +605,8 @@ private:
     bool is_running = false;
     bool is_running = false;
     bool is_sync_cancelled = false;
     bool is_sync_cancelled = false;
 
 
+    bool will_be_terminated{};
+
     std::string name;
     std::string name;
 };
 };