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

Merge branch 'idle-cleanup' into scale-amd64

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