idle threads deallocate etc the kernel thread zombies

上级 bc7ecffc
...@@ -127,6 +127,7 @@ void iderw(struct buf*); ...@@ -127,6 +127,7 @@ void iderw(struct buf*);
// idle.cc // idle.cc
struct proc * idleproc(void); struct proc * idleproc(void);
void idlezombie(struct proc*);
// ioapic.c // ioapic.c
void ioapicenable(int irq, int cpu); void ioapicenable(int irq, int cpu);
...@@ -179,6 +180,7 @@ int pipewrite(struct pipe*, char*, int); ...@@ -179,6 +180,7 @@ int pipewrite(struct pipe*, char*, int);
// proc.c // proc.c
struct proc* allocproc(void); struct proc* allocproc(void);
struct proc* copyproc(struct proc*); struct proc* copyproc(struct proc*);
void finishproc(struct proc*);
void exit(void); void exit(void);
int fork(int); int fork(int);
int growproc(int); int growproc(int);
......
...@@ -8,6 +8,15 @@ ...@@ -8,6 +8,15 @@
#include "sched.hh" #include "sched.hh"
// XXX(sbw) these should be padded out // XXX(sbw) these should be padded out
struct idle {
struct proc *cur;
struct proc *heir;
SLIST_HEAD(zombies, proc) zombies;
struct spinlock lock;
};
struct idle idlem[NCPU] __mpalign__;
struct proc * idlep[NCPU] __mpalign__; struct proc * idlep[NCPU] __mpalign__;
struct heir { struct heir {
...@@ -27,6 +36,14 @@ idleproc(void) ...@@ -27,6 +36,14 @@ idleproc(void)
} }
void void
idlezombie(struct proc *p)
{
acquire(&idlem[mycpu()->id].lock);
SLIST_INSERT_HEAD(&idlem[mycpu()->id].zombies, p, child_next);
release(&idlem[mycpu()->id].lock);
}
void
idlebequeath(void) idlebequeath(void)
{ {
// Only the current idle thread may call this function // Only the current idle thread may call this function
...@@ -54,6 +71,22 @@ idleheir(void *x) ...@@ -54,6 +71,22 @@ idleheir(void *x)
idleloop(); idleloop();
} }
static inline void
finishzombies(void)
{
struct idle *i = &idlem[mycpu()->id];
if (!SLIST_EMPTY(&i->zombies)) {
struct proc *p, *np;
acquire(&i->lock);
SLIST_FOREACH_SAFE(p, &i->zombies, child_next, np) {
SLIST_REMOVE(&i->zombies, p, proc, child_next);
finishproc(p);
}
release(&i->lock);
}
}
void void
idleloop(void) idleloop(void)
{ {
...@@ -78,6 +111,8 @@ idleloop(void) ...@@ -78,6 +111,8 @@ idleloop(void)
myproc()->set_state(RUNNABLE); myproc()->set_state(RUNNABLE);
sched(); sched();
finishzombies();
if (steal() == 0) { if (steal() == 0) {
int worked; int worked;
do { do {
...@@ -114,6 +149,9 @@ initidle(void) ...@@ -114,6 +149,9 @@ initidle(void)
if (!p) if (!p)
panic("initidle allocproc"); panic("initidle allocproc");
SLIST_INIT(&idlem[cpunum()].zombies);
initlock(&idlem[cpunum()].lock, "idle_lock", LOCKSTAT_IDLE);
snprintf(p->name, sizeof(p->name), "idle_%u", cpunum()); snprintf(p->name, sizeof(p->name), "idle_%u", cpunum());
mycpu()->proc = p; mycpu()->proc = p;
myproc()->cpuid = cpunum(); myproc()->cpuid = cpunum();
......
...@@ -83,6 +83,7 @@ cmain(u64 mbmagic, u64 mbaddr) ...@@ -83,6 +83,7 @@ cmain(u64 mbmagic, u64 mbaddr)
initkalloc(mbaddr); initkalloc(mbaddr);
initproc(); // process table initproc(); // process table
initsched(); // scheduler run queues initsched(); // scheduler run queues
initidle();
initgc(); // gc epochs and threads initgc(); // gc epochs and threads
initbio(); // buffer cache initbio(); // buffer cache
initinode(); // inode cache initinode(); // inode cache
...@@ -95,7 +96,6 @@ cmain(u64 mbmagic, u64 mbaddr) ...@@ -95,7 +96,6 @@ cmain(u64 mbmagic, u64 mbaddr)
initlockstat(); initlockstat();
initpci(); initpci();
initnet(); initnet();
initidle();
if (VERBOSE) if (VERBOSE)
cprintf("ncpu %d %lu MHz\n", ncpu, cpuhz / 1000000); cprintf("ncpu %d %lu MHz\n", ncpu, cpuhz / 1000000);
......
...@@ -152,9 +152,13 @@ exit(void) ...@@ -152,9 +152,13 @@ exit(void)
// Parent might be sleeping in wait(). // Parent might be sleeping in wait().
acquire(&(myproc()->lock)); acquire(&(myproc()->lock));
// Kernel threads might not have a parent // Kernel threads might not have a parent
if (myproc()->parent != nullptr) if (myproc()->parent != nullptr)
cv_wakeup(&(myproc()->parent->cv)); cv_wakeup(&(myproc()->parent->cv));
else
idlezombie(myproc());
if (wakeupinit) if (wakeupinit)
cv_wakeup(&bootproc->cv); cv_wakeup(&bootproc->cv);
...@@ -458,6 +462,21 @@ fork(int flags) ...@@ -458,6 +462,21 @@ fork(int flags)
return pid; return pid;
} }
void
finishproc(struct proc *p)
{
ksfree(slab_stack, p->kstack);
p->kstack = 0;
p->vmap->decref();
if (!xnspid->remove(p->pid, &p))
panic("wait: ns_remove");
p->pid = 0;
p->parent = 0;
p->name[0] = 0;
p->killed = 0;
freeproc(p);
}
// Wait for a child process to exit and return its pid. // Wait for a child process to exit and return its pid.
// Return -1 if this process has no children. // Return -1 if this process has no children.
int int
...@@ -478,16 +497,7 @@ wait(void) ...@@ -478,16 +497,7 @@ wait(void)
pid = p->pid; pid = p->pid;
SLIST_REMOVE(&myproc()->childq, p, proc, child_next); SLIST_REMOVE(&myproc()->childq, p, proc, child_next);
release(&myproc()->lock); release(&myproc()->lock);
ksfree(slab_stack, p->kstack); finishproc(p);
p->kstack = 0;
p->vmap->decref();
if (!xnspid->remove(p->pid, &p))
panic("wait: ns_remove");
p->pid = 0;
p->parent = 0;
p->name[0] = 0;
p->killed = 0;
freeproc(p);
return pid; return pid;
} }
release(&p->lock); release(&p->lock);
...@@ -533,8 +543,8 @@ threadalloc(void (*fn)(void *), void *arg) ...@@ -533,8 +543,8 @@ threadalloc(void (*fn)(void *), void *arg)
p->context->rip = (u64)threadstub; p->context->rip = (u64)threadstub;
p->context->r12 = (u64)fn; p->context->r12 = (u64)fn;
p->context->r13 = (u64)arg; p->context->r13 = (u64)arg;
p->parent = myproc(); p->parent = nullptr;
p->cwd = 0; p->cwd = nullptr;
return p; return p;
} }
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论