提交 c3171cdc 创建 作者: Nickolai Zeldovich's avatar Nickolai Zeldovich

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

...@@ -56,4 +56,3 @@ ...@@ -56,4 +56,3 @@
$ apt-get install libjemalloc-dev $ apt-get install libjemalloc-dev
$ make HW=user o.user/utest $ make HW=user o.user/utest
...@@ -33,7 +33,7 @@ UPROGS := $(addprefix $(O)/bin/, $(UPROGS)) ...@@ -33,7 +33,7 @@ UPROGS := $(addprefix $(O)/bin/, $(UPROGS))
$(O)/bin/%.unstripped: $(O)/bin/%.o $(ULIB) $(O)/bin/%.unstripped: $(O)/bin/%.o $(ULIB)
@echo " LD $@" @echo " LD $@"
$(Q)mkdir -p $(@D) $(Q)mkdir -p $(@D)
$(Q)$(LD) $(LDFLAGS) -N -e main -Ttext 0x100000 -o $@ $^ $(Q)$(LD) $(LDFLAGS) -N -Ttext 0x100000 -o $@ $^
$(O)/bin/%: $(O)/bin/%.unstripped $(O)/bin/%: $(O)/bin/%.unstripped
@echo " STRIP $@" @echo " STRIP $@"
......
#if CILKENABLE
template<typename A1>
static void
cilk_call(void (*fn)(A1), A1 a1)
{
cilk_push((void(*)(uptr, uptr))fn, (uptr)a1, (uptr)0);
}
template<typename A1, typename A2>
static void
cilk_call(void (*fn)(A1, A2), A1 a1, A2 a2)
{
cilk_push((void(*)(uptr, uptr))fn, (uptr)a1, (uptr)a2);
}
#else // !CILKENABLE
template<typename A1>
static void
cilk_call(void (*fn)(A1), A1 a1)
{
fn(a1);
}
template<typename A1, typename A2>
static void
cilk_call(void (*fn)(A1, A2), A1 a1, A2 a2)
{
fn(a1, a2);
}
#endif
...@@ -194,11 +194,6 @@ void yield(void); ...@@ -194,11 +194,6 @@ void yield(void);
struct proc* threadalloc(void (*fn)(void*), void *arg); struct proc* threadalloc(void (*fn)(void*), void *arg);
struct proc* threadpin(void (*fn)(void*), void *arg, const char *name, int cpu); struct proc* threadpin(void (*fn)(void*), void *arg, const char *name, int cpu);
// prof.c
extern int profenable;
void profreset(void);
void profdump(void);
// sampler.c // sampler.c
void sampstart(void); void sampstart(void);
int sampintr(struct trapframe*); int sampintr(struct trapframe*);
......
struct profrec {
u64 tot;
u64 cnt;
__padout__;
} __mpalign__;
typedef struct profctr {
const char *name;
struct profrec rec[NCPU] __mpalign__;
__padout__;
} profctr_t;
#if 0 /* not for c++ */
#define DEFINE_PROFCTR(xname) \
profctr_t xname __attribute__((section(".prof"))) = { .name = #xname };
#define prof_start(name) \
u64 __prof##name = profenable ? rdtsc() : 0;
#define prof_end(name) do { \
if (profenable) { \
u64 __eprof##name = rdtsc(); \
u64 __profid = mycpu()->id; \
name.rec[__profid].tot += __eprof##name - __prof##name; \
name.rec[__profid].cnt++; \
} \
} while (0)
#else
#define DEFINE_PROFCTR(x)
#define prof_start(x)
#define prof_end(x)
#endif
...@@ -29,7 +29,6 @@ OBJS = \ ...@@ -29,7 +29,6 @@ OBJS = \
picirq.o \ picirq.o \
pipe.o \ pipe.o \
proc.o \ proc.o \
prof.o \
gc.o \ gc.o \
rnd.o \ rnd.o \
sampler.o \ sampler.o \
......
...@@ -270,18 +270,6 @@ consoleintr(int (*getc)(void)) ...@@ -270,18 +270,6 @@ consoleintr(int (*getc)(void))
case C('W'): case C('W'):
wq_dump(); wq_dump();
break; break;
case C('L'): // Prof stats
profdump();
break;
case C('K'): // Prof enable
profreset();
cprintf("prof enabled\n");
profenable = 1;
break;
case C('I'): // Prof disable
profenable = 0;
cprintf("prof disabled\n");
break;
case C('F'): // kmem stats case C('F'): // kmem stats
kmemprint(); kmemprint();
break; break;
......
...@@ -12,13 +12,12 @@ ...@@ -12,13 +12,12 @@
#include "vm.hh" #include "vm.hh"
#include "elf.hh" #include "elf.hh"
#include "cpu.hh" #include "cpu.hh"
#include "prof.hh" #include "wq.hh"
#include "cilk.hh"
#define USTACKPAGES 2 #define USTACKPAGES 2
#define BRK (USERTOP >> 1) #define BRK (USERTOP >> 1)
static const int odp = 1;
struct eargs { struct eargs {
struct proc *proc; struct proc *proc;
struct inode *ip; struct inode *ip;
...@@ -28,10 +27,8 @@ struct eargs { ...@@ -28,10 +27,8 @@ struct eargs {
}; };
static void static void
dosegment(uptr a0, u64 a1) dosegment(struct eargs *args, u64 off)
{ {
struct eargs *args = (eargs*) a0;
u64 off = a1;
struct vmnode *vmn = nullptr; struct vmnode *vmn = nullptr;
struct proghdr ph; struct proghdr ph;
uptr va_start, va_end; uptr va_start, va_end;
...@@ -39,7 +36,6 @@ dosegment(uptr a0, u64 a1) ...@@ -39,7 +36,6 @@ dosegment(uptr a0, u64 a1)
uptr in_sz; uptr in_sz;
int npg; int npg;
prof_start(dosegment_prof);
if(readi(args->ip, (char*)&ph, off, sizeof(ph)) != sizeof(ph)) if(readi(args->ip, (char*)&ph, off, sizeof(ph)) != sizeof(ph))
goto bad; goto bad;
if(ph.type != ELF_PROG_LOAD) if(ph.type != ELF_PROG_LOAD)
...@@ -55,56 +51,63 @@ dosegment(uptr a0, u64 a1) ...@@ -55,56 +51,63 @@ dosegment(uptr a0, u64 a1)
in_sz = ph.filesz + PGOFFSET(ph.vaddr); in_sz = ph.filesz + PGOFFSET(ph.vaddr);
npg = (va_end - va_start) / PGSIZE; npg = (va_end - va_start) / PGSIZE;
if ((vmn = new vmnode(npg, odp ? ONDEMAND : EAGER, if ((vmn = new vmnode(npg, ONDEMAND,
args->ip, in_off, in_sz)) == 0) args->ip, in_off, in_sz)) == 0)
goto bad; goto bad;
if(args->vmap->insert(vmn, va_start, 1) < 0) if(args->vmap->insert(vmn, va_start, 1) < 0)
goto bad; goto bad;
prof_end(dosegment_prof);
return; return;
bad: bad:
cilk_abort(-1); cilk_abort(-1);
} }
static void __attribute__((unused)) dostack(uptr a0, u64 a1) static void
dostack(struct eargs *args)
{ {
struct vmnode *vmn = nullptr; struct vmnode *vmn = nullptr;
struct eargs *args = (eargs*) a0; uptr argstck[1+MAXARG];
int argc;
uptr sp;
uptr ustack[1+MAXARG+1];
const char *s, *last; const char *s, *last;
s64 argc;
uptr sp;
// User stack should be:
// char argv[argc-1]
// char argv[argc-2]
// ...
// char argv[0]
// char *argv[argc+1]
// u64 argc
prof_start(dostack_prof);
// Allocate a one-page stack at the top of the (user) address space // Allocate a one-page stack at the top of the (user) address space
if((vmn = new vmnode(USTACKPAGES)) == 0) if((vmn = new vmnode(USTACKPAGES)) == 0)
goto bad; goto bad;
if(args->vmap->insert(vmn, USERTOP-(USTACKPAGES*PGSIZE), 1) < 0) if(args->vmap->insert(vmn, USERTOP-(USTACKPAGES*PGSIZE), 1) < 0)
goto bad; goto bad;
// Push argument strings, prepare rest of stack in ustack. for (argc = 0; args->argv[argc]; argc++)
sp = USERTOP;
for(argc = 0; args->argv[argc]; argc++) {
if(argc >= MAXARG) if(argc >= MAXARG)
goto bad; goto bad;
sp -= strlen(args->argv[argc]) + 1;
// Push argument strings
sp = USERTOP;
for(int i = argc-1; i >= 0; i--) {
sp -= strlen(args->argv[i]) + 1;
sp &= ~7; sp &= ~7;
if(args->vmap->copyout(sp, args->argv[argc], strlen(args->argv[argc]) + 1) < 0) if(args->vmap->copyout(sp, args->argv[i], strlen(args->argv[i]) + 1) < 0)
goto bad; goto bad;
ustack[1+argc] = sp; argstck[i] = sp;
} }
ustack[1+argc] = 0; argstck[argc] = 0;
//prof_start(exec3_prof); sp -= (argc+1) * 8;
ustack[0] = 0xffffffffffffffffull; // fake return PC if(args->vmap->copyout(sp, argstck, (argc+1)*8) < 0)
args->proc->tf->rdi = argc; goto bad;
args->proc->tf->rsi = sp - (argc+1)*8;
sp -= (1+argc+1) * 8; sp -= 8;
if(args->vmap->copyout(sp, ustack, (1+argc+1)*8) < 0) if(args->vmap->copyout(sp, &argc, 8) < 0)
goto bad; goto bad;
// Save program name for debugging. // Save program name for debugging.
...@@ -116,26 +119,23 @@ static void __attribute__((unused)) dostack(uptr a0, u64 a1) ...@@ -116,26 +119,23 @@ static void __attribute__((unused)) dostack(uptr a0, u64 a1)
safestrcpy(args->proc->name, last, sizeof(args->proc->name)); safestrcpy(args->proc->name, last, sizeof(args->proc->name));
args->proc->tf->rsp = sp; args->proc->tf->rsp = sp;
prof_end(dostack_prof);
return; return;
bad: bad:
cilk_abort(-1); cilk_abort(-1);
} }
static void __attribute__((unused)) doheap(uptr a0, u64 a1) static void
doheap(struct eargs *args)
{ {
struct vmnode *vmn = nullptr; struct vmnode *vmn = nullptr;
struct eargs *args = (eargs*) a0;
prof_start(doheap_prof);
// Allocate a vmnode for the heap. // Allocate a vmnode for the heap.
// XXX pre-allocate 32 pages.. // XXX pre-allocate 32 pages..
if((vmn = new vmnode(32)) == 0) if((vmn = new vmnode(32)) == 0)
goto bad; goto bad;
if(args->vmap->insert(vmn, BRK, 1) < 0) if(args->vmap->insert(vmn, BRK, 1) < 0)
goto bad; goto bad;
prof_end(doheap_prof);
return; return;
...@@ -154,7 +154,6 @@ exec(const char *path, char **argv) ...@@ -154,7 +154,6 @@ exec(const char *path, char **argv)
int i; int i;
struct vmap *oldvmap; struct vmap *oldvmap;
prof_start(exec_prof);
if((ip = namei(myproc()->cwd, path)) == 0) if((ip = namei(myproc()->cwd, path)) == 0)
return -1; return -1;
...@@ -188,23 +187,14 @@ exec(const char *path, char **argv) ...@@ -188,23 +187,14 @@ exec(const char *path, char **argv)
goto bad; goto bad;
if(type != ELF_PROG_LOAD) if(type != ELF_PROG_LOAD)
continue; continue;
cilk_push(dosegment, (uptr)&args, (uptr)off); cilk_call(dosegment, &args, off);
}
if (odp) {
// iunlock(ip);
} else {
// iunlockput(ip);
iput(ip);
ip = 0;
} }
cilk_push(doheap, (uptr)&args, (uptr)0); cilk_call(doheap, &args);
// dostack reads from the user address space. The wq // dostack reads from the user vm space. wq workers don't switch
// stuff doesn't switch to the user address space. // the user vm.
//cilk_push(dostack, (uptr)&args, (uptr)0); dostack(&args);
dostack((uptr)&args, (uptr)0);
if (cilk_end()) if (cilk_end())
goto bad; goto bad;
...@@ -219,7 +209,6 @@ exec(const char *path, char **argv) ...@@ -219,7 +209,6 @@ exec(const char *path, char **argv)
oldvmap->decref(); oldvmap->decref();
gc_end_epoch(); gc_end_epoch();
prof_end(exec_prof);
return 0; return 0;
bad: bad:
......
#include "types.h"
#include "kernel.hh"
#include "spinlock.h"
#include "condvar.h"
#include "fs.h"
#include "file.hh"
#include "prof.hh"
#include "bits.hh"
#include "amd64.h"
extern profctr_t sprof[];
extern profctr_t eprof[];
int profenable;
void
profreset(void)
{
profctr_t *p = sprof;
for (; p != eprof; p++) {
memset(p->rec, 0, sizeof(p->rec));
}
}
static void
profsum(struct profctr *ctr, u64 *tot, u64 *cnt)
{
for (int i = 0; i < NCPU; i++) {
*tot += ctr->rec[i].tot;
*cnt += ctr->rec[i].cnt;
}
}
void
profdump(void)
{
profctr_t *p = sprof;
for (; p != eprof; p++) {
u64 tot = 0, cnt = 0;
profsum(p, &tot, &cnt);
if (cnt)
cprintf("%s %lu\n", p->name, tot/cnt);
}
sampdump();
}
ULIB = ulib.o usys.o printf.o umalloc.o uthread.o fmt.o stream.o ipc.o \ ULIB = ulib.o usys.o printf.o umalloc.o uthread.o fmt.o stream.o ipc.o \
threads.o threads.o crt.o
ULIB := $(addprefix $(O)/lib/, $(ULIB)) ULIB := $(addprefix $(O)/lib/, $(ULIB))
.PRECIOUS: $(O)/lib/%.o .PRECIOUS: $(O)/lib/%.o
......
.code64
.align 8
.globl _start
_start:
pop %rdi
mov %rsp, %rsi
call main
call exit
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论