mirror of
https://github.com/RGBCube/serenity
synced 2025-05-21 15:35:07 +00:00
Kernel: Various context switch fixes
These changes solve a number of problems with the software context swithcing: * The scheduler lock really should be held throughout context switches * Transitioning from the initial (idle) thread to another needs to hold the scheduler lock * Transitioning from a dying thread to another also needs to hold the scheduler lock * Dying threads cannot necessarily be finalized if they haven't switched out of it yet, so flag them as active while a processor is running it (the Running state may be switched to Dying while it still is actually running)
This commit is contained in:
parent
49f5069b76
commit
2a82a25fec
9 changed files with 235 additions and 89 deletions
|
@ -1046,7 +1046,7 @@ int Process::do_exec(NonnullRefPtr<FileDescription> main_program_description, Ve
|
|||
// and we don't want to deal with faults after this point.
|
||||
u32 new_userspace_esp = new_main_thread->make_userspace_stack_for_main_thread(move(arguments), move(environment));
|
||||
|
||||
// We cli() manually here because we don't want to get interrupted between do_exec()
|
||||
// We enter a critical section here because we don't want to get interrupted between do_exec()
|
||||
// and Processor::assume_context() or the next context switch.
|
||||
// If we used an InterruptDisabler that sti()'d on exit, we might timer tick'd too soon in exec().
|
||||
Processor::current().enter_critical(prev_flags);
|
||||
|
@ -1268,6 +1268,12 @@ int Process::exec(String path, Vector<String> arguments, Vector<String> environm
|
|||
|
||||
auto current_thread = Thread::current();
|
||||
if (current_thread == new_main_thread) {
|
||||
// We need to enter the scheduler lock before changing the state
|
||||
// and it will be released after the context switch into that
|
||||
// thread. We should also still be in our critical section
|
||||
ASSERT(!g_scheduler_lock.is_locked());
|
||||
ASSERT(Processor::current().in_critical() == 1);
|
||||
g_scheduler_lock.lock();
|
||||
current_thread->set_state(Thread::State::Running);
|
||||
Processor::assume_context(*current_thread, prev_flags);
|
||||
ASSERT_NOT_REACHED();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue