提交 4947af9c 创建 作者: Nickolai Zeldovich's avatar Nickolai Zeldovich

yield in exec, preferentially steal threads in the middle of exec.

hopefully this will migrate less state when stealing.
上级 a2bd6f68
...@@ -87,6 +87,7 @@ struct proc : public rcu_freed { ...@@ -87,6 +87,7 @@ struct proc : public rcu_freed {
u64 user_fs_; u64 user_fs_;
u64 unmap_tlbreq_; u64 unmap_tlbreq_;
int exec_cpuid_; int exec_cpuid_;
int in_exec_;
static proc* alloc(); static proc* alloc();
void set_state(procstate_t s); void set_state(procstate_t s);
......
...@@ -196,6 +196,10 @@ exec(const char *path, char **argv) ...@@ -196,6 +196,10 @@ exec(const char *path, char **argv)
cwork* w; cwork* w;
myproc()->exec_cpuid_ = mycpuid(); myproc()->exec_cpuid_ = mycpuid();
myproc()->in_exec_ = 1;
yield();
myproc()->in_exec_ = 0;
if((ip = namei(myproc()->cwd, path)) == 0) if((ip = namei(myproc()->cwd, path)) == 0)
return -1; return -1;
......
...@@ -41,7 +41,7 @@ proc::proc(int npid) : ...@@ -41,7 +41,7 @@ proc::proc(int npid) :
pid(npid), parent(0), tf(0), context(0), killed(0), pid(npid), parent(0), tf(0), context(0), killed(0),
ftable(0), cwd(0), tsc(0), curcycles(0), cpuid(0), epoch(0), ftable(0), cwd(0), tsc(0), curcycles(0), cpuid(0), epoch(0),
cpu_pin(0), runq(0), oncv(0), cv_wakeup(0), cpu_pin(0), runq(0), oncv(0), cv_wakeup(0),
user_fs_(0), unmap_tlbreq_(0), state_(EMBRYO) user_fs_(0), unmap_tlbreq_(0), in_exec_(0), state_(EMBRYO)
{ {
snprintf(lockname, sizeof(lockname), "cv:proc:%d", pid); snprintf(lockname, sizeof(lockname), "cv:proc:%d", pid);
initlock(&lock, lockname+3, LOCKSTAT_PROC); initlock(&lock, lockname+3, LOCKSTAT_PROC);
......
...@@ -133,51 +133,54 @@ int ...@@ -133,51 +133,54 @@ int
steal(void) steal(void)
{ {
struct proc *steal; struct proc *steal;
int i;
int r = 0; int r = 0;
pushcli(); pushcli();
for (i = 1; i < ncpu; i++) { for (int nonexec = 0; nonexec < 2; nonexec++) {
struct runq *q = &runq[(i+mycpu()->id) % ncpu]; for (int i = 1; i < ncpu; i++) {
struct proc *p; struct runq *q = &runq[(i+mycpu()->id) % ncpu];
struct proc *p;
// XXX(sbw) Look for a process to steal. Acquiring q->lock
// then p->lock can result in deadlock. So we acquire // XXX(sbw) Look for a process to steal. Acquiring q->lock
// q->lock, scan for a process, drop q->lock, acquire p->lock, // then p->lock can result in deadlock. So we acquire
// and then check that it's still ok to steal p. // q->lock, scan for a process, drop q->lock, acquire p->lock,
steal = nullptr; // and then check that it's still ok to steal p.
if (tryacquire(&q->lock) == 0) steal = nullptr;
continue; if (tryacquire(&q->lock) == 0)
STAILQ_FOREACH(p, &q->q, runqlink) { continue;
if (p->get_state() == RUNNABLE && !p->cpu_pin && STAILQ_FOREACH(p, &q->q, runqlink) {
p->curcycles != 0 && p->curcycles > VICTIMAGE) if (p->get_state() == RUNNABLE && !p->cpu_pin &&
{ (p->in_exec_ || nonexec) &&
STAILQ_REMOVE(&q->q, p, proc, runqlink); p->curcycles != 0 && p->curcycles > VICTIMAGE)
steal = p; {
break; STAILQ_REMOVE(&q->q, p, proc, runqlink);
steal = p;
break;
}
} }
} release(&q->lock);
release(&q->lock);
if (steal) {
if (steal) { acquire(&steal->lock);
acquire(&steal->lock); if (steal->get_state() == RUNNABLE && !steal->cpu_pin &&
if (steal->get_state() == RUNNABLE && !steal->cpu_pin && steal->curcycles != 0 && steal->curcycles > VICTIMAGE)
steal->curcycles != 0 && steal->curcycles > VICTIMAGE) {
{ steal->curcycles = 0;
steal->curcycles = 0; steal->cpuid = mycpu()->id;
steal->cpuid = mycpu()->id; addrun(steal);
addrun(steal); release(&steal->lock);
r = 1;
goto found;
}
if (steal->get_state() == RUNNABLE)
addrun(steal);
release(&steal->lock); release(&steal->lock);
r = 1;
break;
} }
if (steal->get_state() == RUNNABLE)
addrun(steal);
release(&steal->lock);
} }
} }
found:
popcli(); popcli();
return r; return r;
} }
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论