tasking: continue fixing task_kill
This commit is contained in:
+44
-20
@@ -98,37 +98,61 @@ void scheduler_unlock()
|
||||
//TODO: there's an issue with this. If there's only one task in the queue (or is it there really?),
|
||||
//the scheduler doesn't switch the context to it, but just does nothing
|
||||
void schedule() {
|
||||
if (!current) return;
|
||||
scheduler_lock();
|
||||
|
||||
// Clean any terminated processes in queue
|
||||
Process* prev = NULL;
|
||||
Process* curr = queue;
|
||||
while (curr) {
|
||||
if (curr->state == Terminated) {
|
||||
Process* next = curr->next;
|
||||
if (prev) prev->next = next;
|
||||
else queue = next;
|
||||
|
||||
destroy_page_dir(curr->pagedir);
|
||||
free_page((void*)virt_to_phys(curr->kstack));
|
||||
free_page((void*)virt_to_phys(curr));
|
||||
|
||||
curr = next;
|
||||
Process* p = queue;
|
||||
while (p) {
|
||||
if (p->state == Terminated) {
|
||||
Process* next_proc = p->next;
|
||||
// Unlink from the queue
|
||||
if (prev) {
|
||||
prev->next = next_proc;
|
||||
} else {
|
||||
queue = next_proc;
|
||||
}
|
||||
|
||||
// If the terminated process is the current one, we must not switch to it.
|
||||
if (p == current) {
|
||||
current = NULL;
|
||||
}
|
||||
|
||||
destroy_page_dir(p->pagedir);
|
||||
free_page((void*)virt_to_phys(p->kstack));
|
||||
free_page((void*)virt_to_phys(p));
|
||||
|
||||
p = next_proc;
|
||||
} else {
|
||||
prev = curr;
|
||||
curr = curr->next;
|
||||
prev = p;
|
||||
p = p->next;
|
||||
}
|
||||
}
|
||||
|
||||
Process* next = current->next;
|
||||
// If 'current' was terminated or this is the first run, find a new process.
|
||||
if (!current || current->state != Ready) {
|
||||
current = queue; // Start search from the beginning
|
||||
}
|
||||
|
||||
// Find the next ready process to run
|
||||
Process* next = current ? current->next : NULL;
|
||||
if (!next) next = queue;
|
||||
|
||||
// Iterate through the list to find a process that is ready to run
|
||||
Process* start_node = next;
|
||||
while (next && next->state != Ready) {
|
||||
next = next->next;
|
||||
if (!next) next = queue;
|
||||
if (!next) next = queue; // Wrap around
|
||||
if (next == start_node) { // Full circle, no ready process
|
||||
scheduler_unlock();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!next || next == current) return;
|
||||
|
||||
switchProcess(next);
|
||||
if (next && next != current) {
|
||||
switchProcess(next);
|
||||
}
|
||||
|
||||
scheduler_unlock();
|
||||
}
|
||||
|
||||
void idle()
|
||||
|
||||
Reference in New Issue
Block a user