mirror of
https://github.com/citra-emu/citra.git
synced 2024-11-22 12:10:05 +00:00
Kernel: Implemented priority inheritance for mutexes.
This commit is contained in:
parent
7b9f428b23
commit
9c3419ebcc
@ -56,7 +56,15 @@ SharedPtr<Mutex> Mutex::Create(bool initial_locked, std::string name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Mutex::ShouldWait() {
|
bool Mutex::ShouldWait() {
|
||||||
return lock_count > 0 && holding_thread != GetCurrentThread();;
|
auto thread = GetCurrentThread();
|
||||||
|
bool wait = lock_count > 0 && holding_thread != thread;
|
||||||
|
|
||||||
|
// If the holding thread of the mutex is lower priority than this thread, that thread should
|
||||||
|
// temporarily inherit this thread's priority
|
||||||
|
if (wait && thread->current_priority < holding_thread->current_priority)
|
||||||
|
holding_thread->BoostPriority(thread->current_priority);
|
||||||
|
|
||||||
|
return wait;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mutex::Acquire() {
|
void Mutex::Acquire() {
|
||||||
|
@ -156,9 +156,8 @@ static void PriorityBoostStarvedThreads() {
|
|||||||
u64 delta = current_ticks - thread->last_running_ticks;
|
u64 delta = current_ticks - thread->last_running_ticks;
|
||||||
|
|
||||||
if (thread->status == THREADSTATUS_READY && delta > boost_timeout && !thread->idle) {
|
if (thread->status == THREADSTATUS_READY && delta > boost_timeout && !thread->idle) {
|
||||||
const s32 boost_priority = std::max(ready_queue.get_first()->current_priority - 1, 0);
|
const s32 priority = std::max(ready_queue.get_first()->current_priority - 1, 0);
|
||||||
ready_queue.move(thread, thread->current_priority, boost_priority);
|
thread->BoostPriority(priority);
|
||||||
thread->current_priority = boost_priority;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -435,6 +434,11 @@ void Thread::SetPriority(s32 priority) {
|
|||||||
nominal_priority = current_priority = priority;
|
nominal_priority = current_priority = priority;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Thread::BoostPriority(s32 priority) {
|
||||||
|
ready_queue.move(this, current_priority, priority);
|
||||||
|
current_priority = priority;
|
||||||
|
}
|
||||||
|
|
||||||
SharedPtr<Thread> SetupIdleThread() {
|
SharedPtr<Thread> SetupIdleThread() {
|
||||||
// We need to pass a few valid values to get around parameter checking in Thread::Create.
|
// We need to pass a few valid values to get around parameter checking in Thread::Create.
|
||||||
auto thread = Thread::Create("idle", Memory::KERNEL_MEMORY_VADDR, THREADPRIO_LOWEST, 0,
|
auto thread = Thread::Create("idle", Memory::KERNEL_MEMORY_VADDR, THREADPRIO_LOWEST, 0,
|
||||||
|
@ -89,6 +89,12 @@ public:
|
|||||||
*/
|
*/
|
||||||
void SetPriority(s32 priority);
|
void SetPriority(s32 priority);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Temporarily boosts the thread's priority until the next time it is scheduled
|
||||||
|
* @param priority The new priority
|
||||||
|
*/
|
||||||
|
void BoostPriority(s32 priority);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the thread's thread ID
|
* Gets the thread's thread ID
|
||||||
* @return The thread's ID
|
* @return The thread's ID
|
||||||
|
Loading…
Reference in New Issue
Block a user