提交 05659653 创建 作者: Frans Kaashoek's avatar Frans Kaashoek

Merge commit 'origin/mtrace' into scale

Conflicts: kalloc.c proc.c spinlock.c
......@@ -14,3 +14,6 @@ initcode.out
kernel
mkfs
.gdbinit
mtrace.out
mscan.syms
mscan.kern
......@@ -50,8 +50,16 @@ TOOLPREFIX := $(shell if i386-jos-elf-objdump -i 2>&1 | grep '^elf32-i386$$' >/d
echo "***" 1>&2; exit 1; fi)
endif
# The i386 ('qemu') mtrace doesn't work, but 'qemu-system-x86_64' mtrace works.
MTRACE = qemu-system-x86_64
QEMUSRC ?=
ifeq ($(QEMUSRC),)
$(error You need to set QEMUSRC (e.g. make QEMUSRC=~/qemu))
endif
# If the makefile can't find QEMU, specify its path here
#QEMU =
#QEMU =
# Try to infer the correct QEMU
ifndef QEMU
......@@ -72,7 +80,7 @@ AS = $(TOOLPREFIX)gas
LD = $(TOOLPREFIX)ld
OBJCOPY = $(TOOLPREFIX)objcopy
OBJDUMP = $(TOOLPREFIX)objdump
CFLAGS = -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror
CFLAGS = -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -I$(QEMUSRC)
CFLAGS += $(shell $(CC) -fno-stack-protector -E -x c /dev/null >/dev/null 2>&1 && echo -fno-stack-protector)
ASFLAGS = -m32 -gdwarf-2
# FreeBSD ld wants ``elf_i386_fbsd''
......@@ -163,6 +171,7 @@ UPROGS=\
_usertests\
_wc\
_zombie\
_halt\
fs.img: mkfs README $(UPROGS)
./mkfs fs.img README $(UPROGS)
......@@ -191,6 +200,12 @@ bochs : fs.img xv6.img
if [ ! -e .bochsrc ]; then ln -s dot-bochsrc .bochsrc; fi
bochs -q
mscan.syms: kernel
nm -S $< > $@
mscan.kern: kernel
cp $< $@
# try to generate a unique GDB port
GDBPORT = $(shell expr `id -u` % 5000 + 25000)
# QEMU's gdb stub command line changed in 0.11
......@@ -201,6 +216,7 @@ ifndef CPUS
CPUS := 2
endif
QEMUOPTS = -hdb fs.img xv6.img -smp $(CPUS)
MTRACEOPTS = -mtrace-enable -mtrace-file mtrace.out -mtrace-quantum 10000
qemu: fs.img xv6.img
$(QEMU) -serial mon:stdio $(QEMUOPTS)
......@@ -211,6 +227,9 @@ qemu-memfs: xv6memfs.img
qemu-nox: fs.img xv6.img
$(QEMU) -nographic $(QEMUOPTS)
mtrace-nox: fs.img xv6.img mscan.syms mscan.kern
$(MTRACE) -nographic $(QEMUOPTS) $(MTRACEOPTS)
.gdbinit: .gdbinit.tmpl
sed "s/localhost:1234/localhost:$(GDBPORT)/" < $^ > $@
......
......@@ -4,6 +4,7 @@
#include "types.h"
#include "stat.h"
#include "user.h"
#include "xv6-mtrace.h"
#define N 1000
......@@ -13,13 +14,31 @@ printf(int fd, char *s, ...)
write(fd, s, strlen(s));
}
char*
strncpy(char *s, const char *t, int n)
{
int tlen = strlen((char *)t);
memmove(s, (char *)t, n > tlen ? tlen : n);
if (n > tlen)
s[tlen] = 0;
return s;
}
void*
memcpy(void *dst, const void *src, uint n)
{
return memmove(dst, (void *)src, n);
}
void
forktest(void)
{
struct mtrace_appdata_entry entry;
int n, pid;
printf(1, "fork test\n");
mtrace_enable_set(1, "xv6-forktest");
for(n=0; n<N; n++){
pid = fork();
if(pid < 0)
......@@ -44,8 +63,13 @@ forktest(void)
printf(1, "wait got too many\n");
exit();
}
entry.u64 = n;
mtrace_appdata_register(&entry);
mtrace_enable_set(0, "xv6-forktest");
printf(1, "fork test OK\n");
halt();
}
int
......
#include "types.h"
#include "user.h"
int
main(int argc, char *argv[])
{
halt();
exit();
}
......@@ -11,6 +11,7 @@
#include "queue.h"
#include "proc.h"
#include "kalloc.h"
#include "xv6-mtrace.h"
struct kmem kmems[NCPU];
......@@ -58,9 +59,7 @@ kfree(char *v)
{
struct run *r;
// cprintf("%d: free 0x%x\n", cpu->id, v);
if((uint)v % PGSIZE || v < end || (uint)v >= PHYSTOP)
if((uint)v % PGSIZE || v < end || (uint)v >= PHYSTOP)
panic("kfree");
// Fill with junk to catch dangling refs.
......@@ -70,6 +69,13 @@ kfree(char *v)
r = (struct run*)v;
r->next = kmem->freelist;
kmem->freelist = r;
mtrace_label_register(mtrace_label_block,
r,
0,
0,
0,
RET_EIP());
release(&kmem->lock);
}
......@@ -87,6 +93,12 @@ kalloc(void)
r = kmem->freelist;
if(r)
kmem->freelist = r->next;
mtrace_label_register(mtrace_label_block,
r,
4096,
"kalloc",
sizeof("kalloc"),
RET_EIP());
release(&kmem->lock);
if (r == 0)
cprintf("%d: kalloc out\n", cpunum());
......
......@@ -7,6 +7,7 @@
#include "condvar.h"
#include "queue.h"
#include "proc.h"
#include "xv6-mtrace.h"
struct ptable ptables[NCPU];
struct runq runqs[NCPU];
......@@ -358,6 +359,15 @@ void
scheduler(void)
{
struct proc *p;
int pid;
acquire(&ptable.lock);
pid = nextpid++;
release(&ptable.lock);
// Enabling mtrace calls in scheduler generates many mtrace_call_entrys.
// mtrace_call_set(1, cpunum());
mtrace_fcall_register(pid, (unsigned long)scheduler, 0, mtrace_start);
for(;;){
// Enable interrupts on this processor.
......@@ -380,8 +390,12 @@ scheduler(void)
proc = p;
switchuvm(p);
p->state = RUNNING;
// cprintf("%d: running %d\n", cpu->id, p->pid);
mtrace_fcall_register(pid, 0, 0, mtrace_pause);
mtrace_fcall_register(proc->pid, 0, 0, mtrace_resume);
mtrace_call_set(1, cpunum());
swtch(&cpu->scheduler, proc->context);
mtrace_fcall_register(pid, 0, 0, mtrace_resume);
mtrace_call_set(0, cpunum());
switchkvm();
// Process is done running for now.
......@@ -413,6 +427,9 @@ sched(void)
if(readeflags()&FL_IF)
panic("sched interruptible");
intena = cpu->intena;
mtrace_fcall_register(proc->pid, 0, 0, mtrace_pause);
mtrace_call_set(0, cpunum());
swtch(&proc->context, cpu->scheduler);
cpu->intena = intena;
}
......
......@@ -9,6 +9,7 @@
#include "condvar.h"
#include "queue.h"
#include "proc.h"
#include "xv6-mtrace.h"
void
initlock(struct spinlock *lk, char *name)
......@@ -31,12 +32,24 @@ acquire(struct spinlock *lk)
panic("acquire");
}
mtrace_lock_register(RET_EIP(),
lk,
lk->name,
mtrace_lockop_acquire,
0);
// The xchg is atomic.
// It also serializes, so that reads after acquire are not
// reordered before it.
// reordered before it.
while(xchg(&lk->locked, 1) != 0)
;
mtrace_lock_register(RET_EIP(),
lk,
lk->name,
mtrace_lockop_acquired,
0);
// Record info about lock acquisition for debugging.
lk->cpu = cpu;
getcallerpcs(&lk, lk->pcs);
......@@ -51,10 +64,16 @@ release(struct spinlock *lk)
panic("release");
}
mtrace_lock_register(RET_EIP(),
lk,
lk->name,
mtrace_lockop_release,
0);
lk->pcs[0] = 0;
lk->cpu = 0;
// The xchg serializes, so that reads before release are
// The xchg serializes, so that reads before release are
// not reordered after it. The 1996 PentiumPro manual (Volume 3,
// 7.2) says reads can be carried out speculatively and in
// any order, which implies we need to serialize here.
......@@ -74,7 +93,7 @@ getcallerpcs(void *v, uint pcs[])
{
uint *ebp;
int i;
ebp = (uint*)v - 2;
for(i = 0; i < 10; i++){
if(ebp == 0 || ebp < (uint*)0x100000 || ebp == (uint*)0xffffffff)
......@@ -102,7 +121,7 @@ void
pushcli(void)
{
int eflags;
eflags = readeflags();
cli();
if(cpu->ncli++ == 0)
......
......@@ -8,6 +8,7 @@
#include "proc.h"
#include "x86.h"
#include "syscall.h"
#include "xv6-mtrace.h"
// User code makes a system call with INT T_SYSCALL.
// System call number in %eax.
......@@ -100,6 +101,7 @@ extern int sys_unlink(void);
extern int sys_wait(void);
extern int sys_write(void);
extern int sys_uptime(void);
extern int sys_halt(void);
static int (*syscalls[])(void) = {
[SYS_chdir] sys_chdir,
......@@ -123,17 +125,26 @@ static int (*syscalls[])(void) = {
[SYS_wait] sys_wait,
[SYS_write] sys_write,
[SYS_uptime] sys_uptime,
[SYS_halt] sys_halt,
};
void
syscall(void)
{
int num;
num = proc->tf->eax;
if(num >= 0 && num < NELEM(syscalls) && syscalls[num])
if(num >= 0 && num < NELEM(syscalls) && syscalls[num]) {
mtrace_fcall_register(proc->pid, (unsigned long)syscalls[num],
0,
mtrace_start);
mtrace_call_set(1, cpunum());
proc->tf->eax = syscalls[num]();
else {
mtrace_fcall_register(proc->pid, (unsigned long)syscalls[num],
0,
mtrace_done);
mtrace_call_set(0, cpunum());
} else {
cprintf("%d %s: unknown sys call %d\n",
proc->pid, proc->name, num);
proc->tf->eax = -1;
......
......@@ -20,3 +20,4 @@
#define SYS_sbrk 19
#define SYS_sleep 20
#define SYS_uptime 21
#define SYS_halt 22
......@@ -90,3 +90,14 @@ sys_uptime(void)
release(&tickslock);
return xticks;
}
int
sys_halt(void)
{
int i;
const char s[] = "Shutdown";
for(i = 0; i < 8; i++)
outb(0x8900, s[i]);
return 0;
}
......@@ -22,6 +22,7 @@ int getpid(void);
char* sbrk(int);
int sleep(int);
int uptime(void);
void halt(void);
// ulib.c
int stat(char*, struct stat*);
......
......@@ -29,3 +29,4 @@ SYSCALL(getpid)
SYSCALL(sbrk)
SYSCALL(sleep)
SYSCALL(uptime)
SYSCALL(halt)
#include <stdint.h>
void* memcpy(void *dst, const void *src, uint n);
char* strncpy(char *s, const char *t, int n);
#define RET_EIP() ((unsigned long)__builtin_return_address(0))
#include "mtrace-magic.h"
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论