diff options
Diffstat (limited to 'src/core/hle')
| -rw-r--r-- | src/core/hle/kernel/kernel.cpp | 23 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.h | 2 | ||||
| -rw-r--r-- | src/core/hle/kernel/mutex.cpp | 35 | ||||
| -rw-r--r-- | src/core/hle/kernel/mutex.h | 1 | ||||
| -rw-r--r-- | src/core/hle/svc.cpp | 5 | 
5 files changed, 42 insertions, 24 deletions
| diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index ef9dbafa5..6f61d526a 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -3,7 +3,6 @@  // Refer to the license.txt file included.  #include <algorithm> -#include <boost/range/algorithm_ext/erase.hpp>  #include "common/assert.h"  #include "common/logging/log.h"  #include "core/hle/config_mem.h" @@ -34,10 +33,17 @@ void WaitObject::RemoveWaitingThread(Thread* thread) {  SharedPtr<Thread> WaitObject::GetHighestPriorityReadyThread() {      // Remove the threads that are ready or already running from our waitlist -    boost::range::remove_erase_if(waiting_threads, [](const SharedPtr<Thread>& thread) { -        return thread->status == THREADSTATUS_RUNNING || thread->status == THREADSTATUS_READY || -               thread->status == THREADSTATUS_DEAD; -    }); +    auto to_remove = waiting_threads.end(); +    do { +        to_remove = std::find_if(waiting_threads.begin(), waiting_threads.end(), +                                 [](const SharedPtr<Thread>& thread) { +                                    return thread->status == THREADSTATUS_RUNNING || +                                           thread->status == THREADSTATUS_READY || +                                           thread->status == THREADSTATUS_DEAD; +        }); +        // Call RemoveWaitingThread so that child classes can override the behavior. +        RemoveWaitingThread(to_remove->get()); +    } while (to_remove != waiting_threads.end());      Thread* candidate = nullptr;      s32 candidate_priority = THREADPRIO_LOWEST + 1; @@ -49,9 +55,10 @@ SharedPtr<Thread> WaitObject::GetHighestPriorityReadyThread() {          if (ShouldWait(thread.get()))              continue; -        bool ready_to_run = -            std::none_of(thread->wait_objects.begin(), thread->wait_objects.end(), -                         [&thread](const SharedPtr<WaitObject>& object) { return object->ShouldWait(thread.get()); }); +        bool ready_to_run = std::none_of(thread->wait_objects.begin(), thread->wait_objects.end(), +                                        [&thread](const SharedPtr<WaitObject>& object) { +                                            return object->ShouldWait(thread.get()); +                                        });          if (ready_to_run) {              candidate = thread.get();              candidate_priority = thread->current_priority; diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 2680f89c9..05097824b 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -151,7 +151,7 @@ public:       * Removes a thread from waiting on this object (e.g. if it was resumed already)       * @param thread Pointer to thread to remove       */ -    void RemoveWaitingThread(Thread* thread); +    virtual void RemoveWaitingThread(Thread* thread);      /**       * Wake up all threads waiting on this object that can be awoken, in priority order, diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp index e83717e80..84ff65150 100644 --- a/src/core/hle/kernel/mutex.cpp +++ b/src/core/hle/kernel/mutex.cpp @@ -28,6 +28,23 @@ static void UpdateThreadPriority(Thread* thread) {      thread->SetPriority(best_priority);  } +/** + * Elevate the mutex priority to the best priority + * among the priorities of all its waiting threads. + */ +static void UpdateMutexPriority(Mutex* mutex) { +    s32 best_priority = THREADPRIO_LOWEST; +    for (auto& waiter : mutex->GetWaitingThreads()) { +        if (waiter->current_priority < best_priority) +            best_priority = waiter->current_priority; +    } + +    if (best_priority != mutex->priority) { +        mutex->priority = best_priority; +        UpdateThreadPriority(mutex->holding_thread.get()); +    } +} +  void ReleaseThreadMutexes(Thread* thread) {      for (auto& mtx : thread->held_mutexes) {          mtx->lock_count = 0; @@ -93,20 +110,12 @@ void Mutex::Release() {  void Mutex::AddWaitingThread(SharedPtr<Thread> thread) {      WaitObject::AddWaitingThread(thread); +    UpdateMutexPriority(this); +} -    // Elevate the mutex priority to the best priority -    // among the priorities of all its waiting threads. - -    s32 best_priority = THREADPRIO_LOWEST; -    for (auto& waiter : GetWaitingThreads()) { -        if (waiter->current_priority < best_priority) -            best_priority = waiter->current_priority; -    } - -    if (best_priority != priority) { -        priority = best_priority; -        UpdateThreadPriority(holding_thread.get()); -    } +void Mutex::RemoveWaitingThread(Thread* thread) { +    WaitObject::RemoveWaitingThread(thread); +    UpdateMutexPriority(this);  }  } // namespace diff --git a/src/core/hle/kernel/mutex.h b/src/core/hle/kernel/mutex.h index 3e6adeb17..31f920516 100644 --- a/src/core/hle/kernel/mutex.h +++ b/src/core/hle/kernel/mutex.h @@ -43,6 +43,7 @@ public:      void Acquire(Thread* thread) override;      void AddWaitingThread(SharedPtr<Thread> thread) override; +    void RemoveWaitingThread(Thread* thread) override;      void Release(); diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp index 5d6359344..b6e34a9e9 100644 --- a/src/core/hle/svc.cpp +++ b/src/core/hle/svc.cpp @@ -373,8 +373,9 @@ static ResultCode WaitSynchronizationN(s32* out, Kernel::Handle* handles, s32 ha          return ERR_SYNC_TIMEOUT;      } else {          // Find the first object that is acquirable in the provided list of objects -        auto itr = std::find_if(objects.begin(), objects.end(), -                                [thread](const ObjectPtr& object) { return !object->ShouldWait(thread); }); +        auto itr = std::find_if(objects.begin(), objects.end(), [thread](const ObjectPtr& object) { +            return !object->ShouldWait(thread); +        });          if (itr != objects.end()) {              // We found a ready object, acquire it and set the result value | 
