Fix proc_kill () race, improve scheduler locking
All checks were successful
Build documentation / build-and-deploy (push) Successful in 1m45s
All checks were successful
Build documentation / build-and-deploy (push) Successful in 1m45s
This commit is contained in:
@@ -153,6 +153,7 @@ static struct proc* proc_spawn_rd (char* name) {
|
||||
proc->pdata.regs.cs = 0x18 | 0x03;
|
||||
proc->pdata.regs.rip = aux.entry;
|
||||
proc->lock = SPIN_LOCK_INIT;
|
||||
atomic_store (&proc->state, PROC_READY);
|
||||
#endif
|
||||
|
||||
return proc;
|
||||
@@ -181,26 +182,51 @@ static void proc_register (struct proc* proc) {
|
||||
spin_unlock (&procs_lock);
|
||||
}
|
||||
|
||||
static struct proc *proc_find_sched (void) {
|
||||
struct proc *start = thiscpu->proc_current;
|
||||
struct proc *proc = start->next;
|
||||
|
||||
for (;;) {
|
||||
if (proc == NULL) {
|
||||
proc = thiscpu->proc_run_q;
|
||||
}
|
||||
|
||||
if (atomic_load (&proc->state) == PROC_READY) {
|
||||
return proc;
|
||||
}
|
||||
|
||||
/* No runnable processes found. */
|
||||
if (proc == start) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
proc = proc->next;
|
||||
}
|
||||
}
|
||||
|
||||
void proc_sched (void) {
|
||||
struct proc *next = NULL;
|
||||
|
||||
spin_lock (&thiscpu->lock);
|
||||
|
||||
if (thiscpu->proc_run_q == NULL || thiscpu->proc_current == NULL) {
|
||||
goto done;
|
||||
spin_unlock (&thiscpu->lock);
|
||||
goto idle;
|
||||
}
|
||||
|
||||
thiscpu->proc_current = thiscpu->proc_current->next;
|
||||
next = proc_find_sched ();
|
||||
|
||||
if (thiscpu->proc_current == NULL) {
|
||||
thiscpu->proc_current = thiscpu->proc_run_q;
|
||||
if (next != NULL) {
|
||||
thiscpu->proc_current = next;
|
||||
}
|
||||
|
||||
done:
|
||||
spin_unlock (&thiscpu->lock);
|
||||
|
||||
if (thiscpu->proc_current != NULL) {
|
||||
do_sched (&thiscpu->proc_current->pdata.regs, &thiscpu->proc_current->pd);
|
||||
if (next != NULL && atomic_load (&next->state) == PROC_READY) {
|
||||
do_sched (&next->pdata.regs, &next->pd);
|
||||
}
|
||||
|
||||
idle:
|
||||
#if defined(__x86_64__)
|
||||
extern void amd64_spin (void);
|
||||
|
||||
@@ -209,23 +235,8 @@ done:
|
||||
}
|
||||
|
||||
void proc_kill (struct proc* proc) {
|
||||
spin_lock (&procs_lock);
|
||||
|
||||
spin_lock (&thiscpu->lock);
|
||||
|
||||
linklist_remove (struct procw*, procs, proc->procw);
|
||||
linklist_remove (struct proc*, thiscpu->proc_run_q, proc);
|
||||
|
||||
if (thiscpu->proc_current == proc)
|
||||
thiscpu->proc_current = NULL;
|
||||
|
||||
spin_unlock (&thiscpu->lock);
|
||||
|
||||
spin_unlock (&procs_lock);
|
||||
|
||||
/* clean up */
|
||||
free (proc->procw);
|
||||
free (proc);
|
||||
/* mark for garbage collection */
|
||||
atomic_store (&proc->state, PROC_DEAD);
|
||||
}
|
||||
|
||||
static void proc_irq_sched (void* arg, void* regs) {
|
||||
|
||||
Reference in New Issue
Block a user