idle threads deallocate etc the kernel thread zombies

上级 bc7ecffc
......@@ -127,6 +127,7 @@ void iderw(struct buf*);
// idle.cc
struct proc * idleproc(void);
void idlezombie(struct proc*);
// ioapic.c
void ioapicenable(int irq, int cpu);
......@@ -179,6 +180,7 @@ int pipewrite(struct pipe*, char*, int);
// proc.c
struct proc* allocproc(void);
struct proc* copyproc(struct proc*);
void finishproc(struct proc*);
void exit(void);
int fork(int);
int growproc(int);
......
......@@ -8,6 +8,15 @@
#include "sched.hh"
// 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 heir {
......@@ -27,6 +36,14 @@ idleproc(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)
{
// Only the current idle thread may call this function
......@@ -54,6 +71,22 @@ idleheir(void *x)
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
idleloop(void)
{
......@@ -78,6 +111,8 @@ idleloop(void)
myproc()->set_state(RUNNABLE);
sched();
finishzombies();
if (steal() == 0) {
int worked;
do {
......@@ -114,6 +149,9 @@ initidle(void)
if (!p)
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());
mycpu()->proc = p;
myproc()->cpuid = cpunum();
......
......@@ -83,6 +83,7 @@ cmain(u64 mbmagic, u64 mbaddr)
initkalloc(mbaddr);
initproc(); // process table
initsched(); // scheduler run queues
initidle();
initgc(); // gc epochs and threads
initbio(); // buffer cache
initinode(); // inode cache
......@@ -95,7 +96,6 @@ cmain(u64 mbmagic, u64 mbaddr)
initlockstat();
initpci();
initnet();
initidle();
if (VERBOSE)
cprintf("ncpu %d %lu MHz\n", ncpu, cpuhz / 1000000);
......
......@@ -152,9 +152,13 @@ exit(void)
// Parent might be sleeping in wait().
acquire(&(myproc()->lock));
// Kernel threads might not have a parent
if (myproc()->parent != nullptr)
cv_wakeup(&(myproc()->parent->cv));
cv_wakeup(&(myproc()->parent->cv));
else
idlezombie(myproc());
if (wakeupinit)
cv_wakeup(&bootproc->cv);
......@@ -458,6 +462,21 @@ fork(int flags)
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.
// Return -1 if this process has no children.
int
......@@ -478,16 +497,7 @@ wait(void)
pid = p->pid;
SLIST_REMOVE(&myproc()->childq, p, proc, child_next);
release(&myproc()->lock);
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);
finishproc(p);
return pid;
}
release(&p->lock);
......@@ -533,8 +543,8 @@ threadalloc(void (*fn)(void *), void *arg)
p->context->rip = (u64)threadstub;
p->context->r12 = (u64)fn;
p->context->r13 = (u64)arg;
p->parent = myproc();
p->cwd = 0;
p->parent = nullptr;
p->cwd = nullptr;
return p;
}
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论