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

Some code to help instrument kernel for profiling..

上级 56eccf91
......@@ -46,6 +46,7 @@ OBJS = \
picirq.o \
pipe.o \
proc.o \
prof.o \
rcu.o \
sched.o \
spinlock.o \
......
......@@ -308,6 +308,18 @@ consoleintr(int (*getc)(void))
case C('W'): // Work queue stats
wq_dump();
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;
default:
if(c != 0 && input.e-input.r < INPUT_BUF){
c = (c == '\r') ? '\n' : c;
......
......@@ -13,12 +13,15 @@
#include "elf.h"
#include "cpu.h"
#include "vm.h"
#include "prof.h"
#define USTACKPAGES 2
#define BRK (USERTOP >> 1)
static const int odp = 1;
DEFINE_PROFCTR(dosegment_prof);
struct eargs {
struct inode *ip;
struct vmap *vmap;
......@@ -32,6 +35,7 @@ dosegment(uptr a0, u64 a1)
struct vmnode *vmn = NULL;
struct proghdr ph;
prof_start(dosegment_prof);
if(readi(args->ip, (char*)&ph, off, sizeof(ph)) != sizeof(ph))
goto bad;
if(ph.type != ELF_PROG_LOAD) {
......@@ -63,6 +67,7 @@ dosegment(uptr a0, u64 a1)
if(vmap_insert(args->vmap, vmn, ph.vaddr) < 0)
goto bad;
prof_end(dosegment_prof);
return;
bad:
......
......@@ -204,6 +204,11 @@ int wait(void);
void yield(void);
void migrate(struct proc *);
// prof.c
extern int profenable;
void profreset(void);
void profdump(void);
// rcu.c
void rcuinit(void);
void rcu_begin_write(struct spinlock *);
......
......@@ -13,6 +13,12 @@ SECTIONS
*(.rodata .rodata.* .gnu.linkonce.r.*)
}
. = ALIGN(0x1000);
PROVIDE(sprof = .);
.prof : {
*(.prof)
}
PROVIDE(eprof = .);
. = ALIGN(0x1000);
.data : {
*(.data)
}
......
#include "param.h"
#include "types.h"
#include "spinlock.h"
#include "condvar.h"
#include "fs.h"
#include "file.h"
#include "prof.h"
#include "kernel.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);
}
}
struct profrec {
u64 tot;
u64 cnt;
__padout__;
} __mpalign__;
typedef struct profctr {
const char *name;
struct profrec rec[NCPU] __mpalign__;
__padout__;
} profctr_t;
#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)
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论