More worker clean up

上级 6fb6add0
......@@ -6,13 +6,15 @@ struct padded_length {
};
#if defined (XV6_KERNEL)
#define NWORKERS (NCPU-1)
bool uwq_trywork(void);
#define NWORKERS (NCPU-1)
struct uwq;
struct uwq_worker {
uwq_worker(uwq*, proc*);
long wait();
void exit();
uwq* uwq_;
proc *proc_;
......@@ -24,14 +26,13 @@ struct uwq_worker {
};
struct uwq : public referenced, public rcu_freed {
friend struct uwq_worker;
static uwq* alloc(vmap* vmap, filetable *ftable);
bool haswork();
bool trywork();
void* buffer();
bool tryworker();
void setuentry(uptr uentry);
// XXX(sbw) should be part of struct worker
void tryexit(uwq_worker *w);
virtual void do_gc(void) { delete this; }
......@@ -58,6 +59,4 @@ private:
uwq_worker* worker_[NCPU];
};
int uwq_trywork(void);
#endif
......@@ -9,10 +9,6 @@ size_t wq_size(void);
void initwq(void);
void exitwq(void);
#if defined(XV6_KERNEL)
int uwq_trywork(void);
#endif
struct work {
virtual void run() = 0;
};
......
......@@ -8,6 +8,7 @@
#include "sched.hh"
#include "percpu.hh"
#include "wq.hh"
#include "uwq.hh"
#include "kmtrace.hh"
struct idle {
......@@ -118,9 +119,7 @@ idleloop(void)
idlem->heir = p;
}
// XXX(sbw) what should be the policy here?
worked = uwq_trywork();
if (worked == 1)
if (uwq_trywork())
break;
worked = wq_trywork();
......
//
// XXX
// - workers should have a uwq
// - pin workers
#include "types.h"
#include "amd64.h"
#include "kernel.hh"
......@@ -20,9 +15,11 @@ extern "C" {
#include "kern_c.h"
}
int
bool
uwq_trywork(void)
{
// Returning true means uwq added a thread to the run queue
u64 i, k;
// A "random" victim CPU
......@@ -33,23 +30,24 @@ uwq_trywork(void)
if (j == mycpuid())
continue;
struct cpu *c = &cpus[j];
// The gc_epoch is for p and uwq
scoped_gc_epoch xgc();
barrier();
struct proc *p = c->proc;
if (p == nullptr || p->uwq == nullptr)
continue;
uwq* uwq = p->uwq;
if (uwq->haswork()) {
if (uwq->trywork())
return 1;
// XXX(sbw) start a worker thread..
if (uwq->tryworker())
return true;
break;
}
}
return 0;
return false;
}
long
......@@ -72,14 +70,28 @@ uwq_worker::uwq_worker(uwq* u, proc* p)
initcondvar(&cv_, "worker_cv");
}
void
uwq_worker::exit(void)
{
if (--uwq_->uref_ == 0)
gc_delayed(uwq_);
release(&lock_);
delete this;
::exit();
}
long
uwq_worker::wait(void)
{
acquire(&lock_);
uwq_->tryexit(this);
if (uwq_->ref() == 0)
this->exit();
running_ = false;
cv_sleep(&cv_, &lock_);
uwq_->tryexit(this);
if (uwq_->ref() == 0)
this->exit();
release(&lock_);
return 0;
}
......@@ -140,18 +152,6 @@ uwq::~uwq(void)
ftable_->decref();
}
void
uwq::tryexit(uwq_worker *w)
{
if (ref() == 0) {
if (--uref_ == 0)
gc_delayed(this);
release(&w->lock_);
delete w;
exit();
}
}
bool
uwq::haswork(void)
{
......@@ -167,8 +167,9 @@ uwq::haswork(void)
}
bool
uwq::trywork(void)
uwq::tryworker(void)
{
// Try to start a worker thread
scoped_acquire lock0(&lock_);
if (ref() == 0)
......@@ -249,12 +250,6 @@ uwq::onzero() const
u->finish();
}
void*
uwq::buffer(void)
{
return (void*)len_;
}
void
uwq::setuentry(uptr uentry)
{
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论