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.cs = 0x18 | 0x03;
|
||||||
proc->pdata.regs.rip = aux.entry;
|
proc->pdata.regs.rip = aux.entry;
|
||||||
proc->lock = SPIN_LOCK_INIT;
|
proc->lock = SPIN_LOCK_INIT;
|
||||||
|
atomic_store (&proc->state, PROC_READY);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return proc;
|
return proc;
|
||||||
@@ -181,26 +182,51 @@ static void proc_register (struct proc* proc) {
|
|||||||
spin_unlock (&procs_lock);
|
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) {
|
void proc_sched (void) {
|
||||||
|
struct proc *next = NULL;
|
||||||
|
|
||||||
spin_lock (&thiscpu->lock);
|
spin_lock (&thiscpu->lock);
|
||||||
|
|
||||||
if (thiscpu->proc_run_q == NULL || thiscpu->proc_current == NULL) {
|
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) {
|
if (next != NULL) {
|
||||||
thiscpu->proc_current = thiscpu->proc_run_q;
|
thiscpu->proc_current = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
|
||||||
spin_unlock (&thiscpu->lock);
|
spin_unlock (&thiscpu->lock);
|
||||||
|
|
||||||
if (thiscpu->proc_current != NULL) {
|
if (next != NULL && atomic_load (&next->state) == PROC_READY) {
|
||||||
do_sched (&thiscpu->proc_current->pdata.regs, &thiscpu->proc_current->pd);
|
do_sched (&next->pdata.regs, &next->pd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
idle:
|
||||||
#if defined(__x86_64__)
|
#if defined(__x86_64__)
|
||||||
extern void amd64_spin (void);
|
extern void amd64_spin (void);
|
||||||
|
|
||||||
@@ -209,23 +235,8 @@ done:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void proc_kill (struct proc* proc) {
|
void proc_kill (struct proc* proc) {
|
||||||
spin_lock (&procs_lock);
|
/* mark for garbage collection */
|
||||||
|
atomic_store (&proc->state, PROC_DEAD);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void proc_irq_sched (void* arg, void* regs) {
|
static void proc_irq_sched (void* arg, void* regs) {
|
||||||
|
|||||||
@@ -11,6 +11,12 @@
|
|||||||
#include <amd64/proc.h> /* USTACK_SIZE */
|
#include <amd64/proc.h> /* USTACK_SIZE */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/// Process is ready to run
|
||||||
|
#define PROC_READY 0
|
||||||
|
/// Process marked garbage collection
|
||||||
|
#define PROC_DEAD 1
|
||||||
|
|
||||||
|
|
||||||
struct cpu;
|
struct cpu;
|
||||||
|
|
||||||
struct proc_mapping {
|
struct proc_mapping {
|
||||||
@@ -30,6 +36,7 @@ struct proc {
|
|||||||
spin_lock_t lock;
|
spin_lock_t lock;
|
||||||
struct cpu* cpu;
|
struct cpu* cpu;
|
||||||
struct procw* procw; /* link to it's global struct */
|
struct procw* procw; /* link to it's global struct */
|
||||||
|
atomic_int state;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
Reference in New Issue
Block a user