提交 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 {
u64 user_fs_;
u64 unmap_tlbreq_;
int exec_cpuid_;
int in_exec_;
static proc* alloc();
void set_state(procstate_t s);
......
......@@ -196,6 +196,10 @@ exec(const char *path, char **argv)
cwork* w;
myproc()->exec_cpuid_ = mycpuid();
myproc()->in_exec_ = 1;
yield();
myproc()->in_exec_ = 0;
if((ip = namei(myproc()->cwd, path)) == 0)
return -1;
......
......@@ -41,7 +41,7 @@ proc::proc(int npid) :
pid(npid), parent(0), tf(0), context(0), killed(0),
ftable(0), cwd(0), tsc(0), curcycles(0), cpuid(0), epoch(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);
initlock(&lock, lockname+3, LOCKSTAT_PROC);
......
......@@ -133,51 +133,54 @@ int
steal(void)
{
struct proc *steal;
int i;
int r = 0;
pushcli();
for (i = 1; i < ncpu; i++) {
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
// q->lock, scan for a process, drop q->lock, acquire p->lock,
// and then check that it's still ok to steal p.
steal = nullptr;
if (tryacquire(&q->lock) == 0)
continue;
STAILQ_FOREACH(p, &q->q, runqlink) {
if (p->get_state() == RUNNABLE && !p->cpu_pin &&
p->curcycles != 0 && p->curcycles > VICTIMAGE)
{
STAILQ_REMOVE(&q->q, p, proc, runqlink);
steal = p;
break;
for (int nonexec = 0; nonexec < 2; nonexec++) {
for (int i = 1; i < ncpu; i++) {
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
// q->lock, scan for a process, drop q->lock, acquire p->lock,
// and then check that it's still ok to steal p.
steal = nullptr;
if (tryacquire(&q->lock) == 0)
continue;
STAILQ_FOREACH(p, &q->q, runqlink) {
if (p->get_state() == RUNNABLE && !p->cpu_pin &&
(p->in_exec_ || nonexec) &&
p->curcycles != 0 && p->curcycles > VICTIMAGE)
{
STAILQ_REMOVE(&q->q, p, proc, runqlink);
steal = p;
break;
}
}
}
release(&q->lock);
if (steal) {
acquire(&steal->lock);
if (steal->get_state() == RUNNABLE && !steal->cpu_pin &&
steal->curcycles != 0 && steal->curcycles > VICTIMAGE)
{
steal->curcycles = 0;
steal->cpuid = mycpu()->id;
addrun(steal);
release(&q->lock);
if (steal) {
acquire(&steal->lock);
if (steal->get_state() == RUNNABLE && !steal->cpu_pin &&
steal->curcycles != 0 && steal->curcycles > VICTIMAGE)
{
steal->curcycles = 0;
steal->cpuid = mycpu()->id;
addrun(steal);
release(&steal->lock);
r = 1;
goto found;
}
if (steal->get_state() == RUNNABLE)
addrun(steal);
release(&steal->lock);
r = 1;
break;
}
if (steal->get_state() == RUNNABLE)
addrun(steal);
release(&steal->lock);
}
}
found:
popcli();
return r;
}
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论