Add mtrace hooks to spinlock and kalloc.

上级 f70ef994
......@@ -49,6 +49,12 @@ TOOLPREFIX := $(shell if i386-jos-elf-objdump -i 2>&1 | grep '^elf32-i386$$' >/d
echo "***" 1>&2; exit 1; fi)
endif
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 =
......@@ -71,7 +77,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''
......
......@@ -7,6 +7,7 @@
#include "param.h"
#include "mmu.h"
#include "spinlock.h"
#include "xv6-mtrace.h"
struct run {
struct run *next;
......@@ -41,7 +42,7 @@ kfree(char *v)
{
struct run *r;
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.
......@@ -51,6 +52,14 @@ 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);
}
......@@ -66,6 +75,14 @@ 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);
return (char*)r;
}
......
......@@ -7,6 +7,7 @@
#include "mmu.h"
#include "proc.h"
#include "spinlock.h"
#include "xv6-mtrace.h"
void
initlock(struct spinlock *lk, char *name)
......@@ -27,12 +28,24 @@ acquire(struct spinlock *lk)
if(holding(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);
......@@ -45,10 +58,16 @@ release(struct spinlock *lk)
if(!holding(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.
......@@ -68,7 +87,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)
......@@ -96,7 +115,7 @@ void
pushcli(void)
{
int eflags;
eflags = readeflags();
cli();
if(cpu->ncli++ == 0)
......
#include <stdint.h>
void* memcpy(void *dst, const void *src, uint n);
#define RET_EIP() ((unsigned long)__builtin_return_address(0))
#include "mtrace-magic.h"
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论