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

Merge branch 'scale-amd64' of git+ssh://amsterdam.csail.mit.edu/home/am0/6.828/xv6 into scale-amd64

#include "types.h"
#include "stat.h"
#include "user.h"
#include "mtrace.h"
#define NCHILD 2
#define NDEPTH 7
......@@ -11,7 +10,6 @@ forktree(int depth)
{
if (depth == 0) {
fprintf(1, "%d: forkexectree\n", getpid());
mtenable("xv6-forkexectree");
}
if (depth >= NDEPTH)
......@@ -48,9 +46,6 @@ forktree(int depth)
if (depth > 0)
exit();
mtops(0);
mtdisable("xv6-forkexectree");
fprintf(1, "%d: forkexectree OK\n", getpid());
// halt();
}
......
......@@ -86,6 +86,8 @@ struct proc : public rcu_freed {
LIST_ENTRY(proc) cv_sleep; // Linked list of processes sleeping on a cv
u64 user_fs_;
u64 unmap_tlbreq_;
int exec_cpuid_;
int in_exec_;
static proc* alloc();
void set_state(procstate_t s);
......
......@@ -4,6 +4,7 @@ class work;
int wq_trywork(void);
int wq_push(work *w);
int wq_pushto(work *w, int tcpuid);
void wq_dump(void);
size_t wq_size(void);
void initwq(void);
......
......@@ -173,17 +173,33 @@ bad:
cilk_abort(-1);
}
static void
exec_cleanup(vmap *oldvmap, uwq *olduwq)
{
if (olduwq != nullptr)
olduwq->dec();
oldvmap->decref();
}
int
exec(const char *path, char **argv)
{
struct inode *ip = nullptr;
struct vmap *vmp = nullptr;
uwq* uwq = nullptr;
uwq* newuwq = nullptr;
struct elfhdr elf;
struct proghdr ph;
u64 off;
int i;
struct vmap *oldvmap;
vmap* oldvmap;
uwq* olduwq;
cwork* w;
myproc()->exec_cpuid_ = mycpuid();
myproc()->in_exec_ = 1;
yield();
myproc()->in_exec_ = 0;
if((ip = namei(myproc()->cwd, path)) == 0)
return -1;
......@@ -204,7 +220,7 @@ exec(const char *path, char **argv)
if((vmp = vmap::alloc()) == 0)
goto bad;
if((uwq = uwq::alloc(vmp, myproc()->ftable)) == 0)
if((newuwq = uwq::alloc(vmp, myproc()->ftable)) == 0)
goto bad;
// Arguments for work queue
......@@ -223,7 +239,7 @@ exec(const char *path, char **argv)
sizeof(type)) != sizeof(type))
goto bad;
if (type == ELF_PROG_NOTE) {
if (donotes(ip, uwq, off) < 0) {
if (donotes(ip, newuwq, off) < 0) {
cilk_abort(-1);
break;
}
......@@ -243,14 +259,19 @@ exec(const char *path, char **argv)
// Commit to the user image.
oldvmap = myproc()->vmap;
olduwq = myproc()->uwq;
myproc()->vmap = vmp;
if (myproc()->uwq != nullptr)
myproc()->uwq->dec();
myproc()->uwq = uwq;
myproc()->uwq = newuwq;
myproc()->tf->rip = elf.entry;
switchvm(myproc());
oldvmap->decref();
w = new cwork();
assert(w);
w->rip = (void*) exec_cleanup;
w->arg0 = oldvmap;
w->arg1 = olduwq;
assert(wq_pushto(w, myproc()->exec_cpuid_) >= 0);
gc_end_epoch();
return 0;
......@@ -259,8 +280,8 @@ exec(const char *path, char **argv)
cprintf("exec failed\n");
if(vmp)
vmp->decref();
if(uwq)
uwq->dec();
if(newuwq)
newuwq->dec();
gc_end_epoch();
return 0;
}
......@@ -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);
......
......@@ -13,6 +13,7 @@
#include "vm.hh"
enum { sched_debug = 0 };
enum { steal_nonexec = 1 };
struct runq {
STAILQ_HEAD(queue, proc) q;
......@@ -133,51 +134,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 < (steal_nonexec ? 2 : 1); 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;
}
......
......@@ -428,6 +428,9 @@ sys_exec(const char *path, u64 uargv)
if(argcheckstr(path) < 0) {
return -1;
}
mt_ascope ascope("%s(%s)", __func__, path);
memset(argv, 0, sizeof(argv));
for(i=0;; i++){
if(i >= NELEM(argv))
......
......@@ -12,7 +12,7 @@
class wq {
public:
wq();
int push(work *w);
int push(work *w, int tcpuid);
int trywork();
void dump();
......@@ -57,7 +57,13 @@ wq_size(void)
int
wq_push(work *w)
{
return wq_->push(w);
return wq_->push(w, mycpuid());
}
int
wq_pushto(work *w, int tcpuid)
{
return wq_->push(w, tcpuid);
}
int
......@@ -128,24 +134,24 @@ wq::declen(int c)
}
int
wq::push(work *w)
wq::push(work *w, int tcpuid)
{
int i;
pushcli();
i = q_->head;
if ((i - q_->tail) == NSLOTS) {
stat_->full++;
popcli();
acquire(&q_[tcpuid].lock);
i = q_[tcpuid].head;
if ((i - q_[tcpuid].tail) == NSLOTS) {
stat_[tcpuid].full++;
release(&q_[tcpuid].lock);
return -1;
}
i = i & (NSLOTS-1);
q_->w[i] = w;
q_[tcpuid].w[i] = w;
barrier();
q_->head++;
inclen(mycpuid());
stat_->push++;
popcli();
q_[tcpuid].head++;
inclen(tcpuid);
stat_[tcpuid].push++;
release(&q_[tcpuid].lock);
return 0;
}
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论