提交 bc7ecffc 创建 作者: Silas Boyd-Wickizer's avatar Silas Boyd-Wickizer

Merge branch 'idle-cleanup' into scale-amd64

......@@ -126,7 +126,7 @@ void ideintr(void);
void iderw(struct buf*);
// idle.cc
extern struct proc *idlep[NCPU];
struct proc * idleproc(void);
// ioapic.c
void ioapicenable(int irq, int cpu);
......
......@@ -47,6 +47,7 @@ struct klockstat;
#define LOCKSTAT_CRANGE 1
#define LOCKSTAT_FS 1
#define LOCKSTAT_GC 1
#define LOCKSTAT_IDLE 1
#define LOCKSTAT_KALLOC 1
#define LOCKSTAT_KMALLOC 1
#define LOCKSTAT_NET 1
......
......@@ -92,3 +92,4 @@ sys_async(int fd, size_t count, off_t off,
msg->submitted = 1;
return 0;
}
......@@ -7,11 +7,60 @@
#include "cpu.hh"
#include "sched.hh"
struct proc *idlep[NCPU] __mpalign__;
// XXX(sbw) these should be padded out
struct proc * idlep[NCPU] __mpalign__;
struct heir {
struct proc *proc;
__padout__;
} __mpalign__;
struct heir heir[NCPU] __mpalign__;
void idleloop(void);
struct proc *
idleproc(void)
{
assert(mycpu()->ncli > 0);
return idlep[mycpu()->id];
}
void
idlebequeath(void)
{
// Only the current idle thread may call this function
struct heir *h;
assert(mycpu()->ncli > 0);
assert(myproc() == idlep[mycpu()->id]);
h = &heir[mycpu()->id];
assert(h->proc != nullptr);
idlep[mycpu()->id] = h->proc;
acquire(&h->proc->lock);
h->proc->set_state(RUNNABLE);
release(&h->proc->lock);
}
static void
idleheir(void *x)
{
post_swtch();
heir[mycpu()->id].proc = nullptr;
idleloop();
}
void
idleloop(void)
{
struct heir *h;
h = &heir[mycpu()->id];
// Test the work queue
//extern void testwq(void);
//testwq();
......@@ -33,7 +82,25 @@ idleloop(void)
int worked;
do {
assert(mycpu()->ncli == 0);
// If we don't have an heir, try to allocate one
if (h->proc == nullptr) {
struct proc *p;
p = allocproc();
if (p == nullptr)
break;
snprintf(p->name, sizeof(p->name), "idleh_%u", mycpu()->id);
p->cpuid = mycpu()->id;
p->cpu_pin = 1;
p->context->rip = (u64)idleheir;
p->cwd = nullptr;
h->proc = p;
}
worked = wq_trywork();
// If we are no longer the idle thread, exit
if (worked && idlep[mycpu()->id] != myproc())
exit();
} while(worked);
sti();
}
......@@ -43,13 +110,13 @@ idleloop(void)
void
initidle(void)
{
// allocate a fake PID for each scheduler thread
struct proc *p = allocproc();
if (!p)
panic("initidle allocproc");
snprintf(p->name, sizeof(p->name), "idle_%u", cpunum());
mycpu()->proc = p;
myproc()->cpuid = cpunum();
myproc()->cpu_pin = 1;
idlep[cpunum()] = p;
}
......@@ -26,7 +26,7 @@ void
post_swtch(void)
{
if (mycpu()->prev->get_state() == RUNNABLE &&
mycpu()->prev != idlep[mycpu()->id])
mycpu()->prev != idleproc())
addrun(mycpu()->prev);
release(&mycpu()->prev->lock);
}
......@@ -42,6 +42,11 @@ sched(void)
if(!holding(&myproc()->lock))
panic("sched proc->lock");
#endif
if (myproc() == idleproc() &&
myproc()->get_state() != RUNNABLE) {
extern void idlebequeath(void);
idlebequeath();
}
if(mycpu()->ncli != 1)
panic("sched locks");
if(myproc()->get_state() == RUNNING)
......@@ -59,7 +64,7 @@ sched(void)
struct proc *next = schednext();
if (next == nullptr) {
if (myproc()->get_state() != RUNNABLE) {
next = idlep[mycpu()->id];
next = idleproc();
} else {
myproc()->set_state(RUNNING);
mycpu()->intena = intena;
......
......@@ -175,11 +175,11 @@ wq_trywork(void)
struct work *w;
int i;
pushcli();
//pushcli();
w = __wq_pop(mycpu()->id);
if (w != nullptr) {
__wq_run(w);
popcli();
//popcli();
return 1;
}
// XXX(sbw) should be random
......@@ -190,12 +190,12 @@ wq_trywork(void)
w = __wq_steal(i);
if (w != nullptr) {
__wq_run(w);
popcli();
//popcli();
return 1;
}
}
popcli();
//popcli();
return 0;
}
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论