1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 02:48:11 +00:00

Kernel: Release the big process lock while yielding in sys$yield()

Otherwise, a thread calling sched_yield() will prevent other threads
in that process from entering the kernel.
This commit is contained in:
Andreas Kling 2019-11-16 12:18:59 +01:00
parent 39e2b69153
commit 73d6a69b3f
3 changed files with 5 additions and 8 deletions

View file

@ -3323,7 +3323,8 @@ int Process::sys$putch(char ch)
int Process::sys$yield() int Process::sys$yield()
{ {
return Scheduler::yield(); current->yield_without_holding_big_lock();
return 0;
} }
int Process::sys$beep() int Process::sys$beep()

View file

@ -171,12 +171,8 @@ void Thread::die_if_needed()
Scheduler::pick_next_and_switch_now(); Scheduler::pick_next_and_switch_now();
} }
void Thread::block_helper() void Thread::yield_without_holding_big_lock()
{ {
// This function mostly exists to avoid circular header dependencies. If
// anything needs adding, think carefully about whether it belongs in
// block() instead. Remember that we're unlocking here, so be very careful
// about altering any state once we're unlocked!
bool did_unlock = process().big_lock().unlock_if_locked(); bool did_unlock = process().big_lock().unlock_if_locked();
Scheduler::yield(); Scheduler::yield();
if (did_unlock) if (did_unlock)

View file

@ -267,7 +267,7 @@ public:
set_state(Thread::Blocked); set_state(Thread::Blocked);
// Yield to the scheduler, and wait for us to resume unblocked. // Yield to the scheduler, and wait for us to resume unblocked.
block_helper(); yield_without_holding_big_lock();
// We should no longer be blocked once we woke up // We should no longer be blocked once we woke up
ASSERT(state() != Thread::Blocked); ASSERT(state() != Thread::Blocked);
@ -380,7 +380,7 @@ private:
bool m_dump_backtrace_on_finalization { false }; bool m_dump_backtrace_on_finalization { false };
bool m_should_die { false }; bool m_should_die { false };
void block_helper(); void yield_without_holding_big_lock();
}; };
HashTable<Thread*>& thread_table(); HashTable<Thread*>& thread_table();