citra-emu
/
citra-canary
Archived
1
0
Fork 0

Kernel: Implemented priority inheritance for mutexes.

This commit is contained in:
bunnei 2015-04-03 18:40:16 -04:00
parent 7b9f428b23
commit 9c3419ebcc
3 changed files with 22 additions and 4 deletions

View File

@ -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() {

View File

@ -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,

View File

@ -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