提交 706ea3fe 创建 作者: 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

...@@ -19,6 +19,7 @@ AS = $(TOOLPREFIX)gas ...@@ -19,6 +19,7 @@ AS = $(TOOLPREFIX)gas
LD = $(TOOLPREFIX)ld LD = $(TOOLPREFIX)ld
NM = $(TOOLPREFIX)nm NM = $(TOOLPREFIX)nm
OBJCOPY = $(TOOLPREFIX)objcopy OBJCOPY = $(TOOLPREFIX)objcopy
STRIP = $(TOOLPREFIX)strip
COMFLAGS := -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall \ COMFLAGS := -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall \
-MD -ggdb -m64 -Werror -fms-extensions -mno-sse \ -MD -ggdb -m64 -Werror -fms-extensions -mno-sse \
...@@ -79,7 +80,7 @@ OBJS = \ ...@@ -79,7 +80,7 @@ OBJS = \
incbin.o incbin.o
OBJS := $(addprefix $(O)/, $(OBJS)) OBJS := $(addprefix $(O)/, $(OBJS))
ULIB = ulib.o usys.o printf.o umalloc.o uthread.o ULIB = ulib.o usys.o printf.o umalloc.o uthread.o fmt.o
ULIB := $(addprefix $(O)/, $(ULIB)) ULIB := $(addprefix $(O)/, $(ULIB))
UPROGS= \ UPROGS= \
...@@ -142,10 +143,14 @@ xv6memfs.img: bootblock kernelmemfs ...@@ -142,10 +143,14 @@ xv6memfs.img: bootblock kernelmemfs
dd if=bootblock of=xv6memfs.img conv=notrunc dd if=bootblock of=xv6memfs.img conv=notrunc
dd if=kernelmemfs of=xv6memfs.img seek=1 conv=notrunc dd if=kernelmemfs of=xv6memfs.img seek=1 conv=notrunc
$(O)/_%: $(O)/%.o $(ULIB) $(O)/_%.unstripped: $(O)/%.o $(ULIB)
@echo " LD $@" @echo " LD $@"
$(Q)$(LD) $(LDFLAGS) -N -e main -Ttext 0x100000 -o $@ $^ $(Q)$(LD) $(LDFLAGS) -N -e main -Ttext 0x100000 -o $@ $^
$(O)/_%: $(O)/_%.unstripped
@echo " STRIP $@"
$(Q)$(STRIP) -o $@ $<
$(O)/mkfs: mkfs.c fs.h $(O)/mkfs: mkfs.c fs.h
gcc -m32 -Werror -Wall -o $@ mkfs.c gcc -m32 -Werror -Wall -o $@ mkfs.c
...@@ -162,7 +167,7 @@ mscan.kern: $(O)/kernel ...@@ -162,7 +167,7 @@ mscan.kern: $(O)/kernel
-include *.d -include *.d
-include $(O)/*.d -include $(O)/*.d
.PRECIOUS: $(O)/%.o .PRECIOUS: $(O)/%.o $(O)/_%.unstripped
.PHONY: clean qemu gdb rsync .PHONY: clean qemu gdb rsync
## ##
......
...@@ -2,3 +2,11 @@ ...@@ -2,3 +2,11 @@
#define __mpalign__ __attribute__((aligned(CACHELINE))) #define __mpalign__ __attribute__((aligned(CACHELINE)))
#define __noret__ __attribute__((noreturn)) #define __noret__ __attribute__((noreturn))
#define barrier() __asm volatile("" ::: "memory") #define barrier() __asm volatile("" ::: "memory")
#ifdef __cplusplus
#define BEGIN_DECLS extern "C" {
#define END_DECLS }
#else
#define BEGIN_DECLS
#define END_DECLS
#endif
extern "C" { extern "C" {
#include "types.h" #include "types.h"
#include "kernel.h"
#include <stddef.h> #include <stddef.h>
#include <stdarg.h> #include <stdarg.h>
#include "fmt.h" #include "fmt.h"
#include "lib.h"
unsigned int strlen(const char*);
} }
// //
......
struct ipcctl { struct ipcctl {
volatile char done; volatile char done:1;
volatile char submitted:1;
off_t off;
volatile long result; volatile long result;
}; };
...@@ -294,7 +294,7 @@ void* memmove(void*, const void*, u32); ...@@ -294,7 +294,7 @@ void* memmove(void*, const void*, u32);
void* memset(void*, int, u32); void* memset(void*, int, u32);
void* memcpy(void*, const void *, u32); void* memcpy(void*, const void *, u32);
char* safestrcpy(char*, const char*, u32); char* safestrcpy(char*, const char*, u32);
int strlen(const char*); unsigned int strlen(const char*);
int strncmp(const char*, const char*, u32); int strncmp(const char*, const char*, u32);
char* strncpy(char*, const char*, u32); char* strncpy(char*, const char*, u32);
int strcmp(const char *p, const char *q); int strcmp(const char *p, const char *q);
......
...@@ -32,6 +32,8 @@ pread_work(struct work *w, void *a0, void *a1, void *a2, void *a3) ...@@ -32,6 +32,8 @@ pread_work(struct work *w, void *a0, void *a1, void *a2, void *a3)
ipc->result = r; ipc->result = r;
barrier(); barrier();
ipc->done = 1; ipc->done = 1;
iput(ip);
} }
static struct work * static struct work *
...@@ -57,18 +59,25 @@ sys_kernlet(int fd, size_t count, off_t off) ...@@ -57,18 +59,25 @@ sys_kernlet(int fd, size_t count, off_t off)
{ {
struct file *f; struct file *f;
struct work *w; struct work *w;
struct ipcctl *ipc = (struct ipcctl *)myproc()->vmap->kshared;
if(fd < 0 || fd >= NOFILE || (f=myproc()->ofile[fd]) == 0) if(fd < 0 || fd >= NOFILE || (f=myproc()->ofile[fd]) == 0)
return -1; return -1;
if(f->type != FD_INODE) if(f->type != FD_INODE)
return -1; return -1;
fetchadd(&f->ip->ref, 1);
w = pread_allocwork(f->ip, myproc()->vmap->kshared, count, off); w = pread_allocwork(f->ip, myproc()->vmap->kshared, count, off);
if (w == NULL) if (w == NULL) {
iput(f->ip);
return -1; return -1;
}
if (wq_push(w) < 0) { if (wq_push(w) < 0) {
iput(f->ip);
freework(w); freework(w);
return -1; return -1;
} }
ipc->off = off;
ipc->submitted = 1;
return 0; return 0;
} }
...@@ -16,12 +16,12 @@ UPROGS += \ ...@@ -16,12 +16,12 @@ UPROGS += \
CFLAGS += -Ilwip/src/include -Inet -Ilwip/src/include/ipv4 -I. -DLWIP CFLAGS += -Ilwip/src/include -Inet -Ilwip/src/include/ipv4 -I. -DLWIP
CXXFLAGS += -Ilwip/src/include -Inet -Ilwip/src/include/ipv4 -I. -DLWIP CXXFLAGS += -Ilwip/src/include -Inet -Ilwip/src/include/ipv4 -I. -DLWIP
LWIP_CFLAGS = -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb \ LWIP_CFLAGS = $(COMFLAGS) -std=c99 \
-m64 -Werror -std=c99 -fms-extensions -mno-sse -mcmodel=large -I$(QEMUSRC) \ -Wno-attributes \
-fno-omit-frame-pointer -DHW_$(HW) -include param.h -include compiler.h \ -Wno-address \
-DXV6 -Wno-attributes -Wno-address -Wno-char-subscripts \ -Wno-char-subscripts \
-Wno-unused-but-set-variable -Wno-format -Wno-unused-but-set-variable \
LWIP_CFLAGS += $(shell $(CC) -fno-stack-protector -E -x c /dev/null >/dev/null 2>&1 && echo -fno-stack-protector) -Wno-format
LWIP_INCLUDES := \ LWIP_INCLUDES := \
-Ilwip/src/include \ -Ilwip/src/include \
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
#include "stat.h" #include "stat.h"
#include "fcntl.h" #include "fcntl.h"
#include "user.h" #include "user.h"
#include "lib.h"
#include "amd64.h" #include "amd64.h"
#include "ipc.h" #include "ipc.h"
...@@ -24,6 +25,31 @@ kernlet_pread(int fd, size_t count, off_t off) ...@@ -24,6 +25,31 @@ kernlet_pread(int fd, size_t count, off_t off)
die("kernlet"); die("kernlet");
} }
static ssize_t
xpread(int fd, void *buf, size_t count, off_t off)
{
if (ipcctl->submitted) {
while (ipcctl->done == 0)
nop_pause();
if (ipcctl->result == -1)
goto slow;
if (off < ipcctl->off)
goto slow;
if (off > ipcctl->off + ipcctl->result)
goto slow;
char *kbuf = (char*) (KSHARED+4096);
off_t kbufoff = off - ipcctl->off;
size_t kbufcount = MIN(count, ipcctl->result - kbufoff);
memmove(buf, kbuf+kbufoff, kbufcount);
return kbufcount;
}
slow:
return pread(fd, buf, count, off);
}
int int
main(int ac, char **av) main(int ac, char **av)
{ {
...@@ -43,13 +69,8 @@ main(int ac, char **av) ...@@ -43,13 +69,8 @@ main(int ac, char **av)
for (k = 0; k < FSIZE; k+=PSIZE) { for (k = 0; k < FSIZE; k+=PSIZE) {
kernlet_pread(fd, PSIZE, k); kernlet_pread(fd, PSIZE, k);
while (ipcctl->done == 0)
nop_pause();
die("preadtest: %d\n", (int)ipcctl->result);
for (i = k; i < k+PSIZE; i+=BSIZE) for (i = k; i < k+PSIZE; i+=BSIZE)
if (pread(fd, buf, BSIZE, i) != BSIZE) if (xpread(fd, buf, BSIZE, i) != BSIZE)
die("pread failed"); die("pread failed");
} }
t1 = rdtsc(); t1 = rdtsc();
......
#include "types.h" #include "types.h"
#include "stat.h" #include "stat.h"
#include "user.h" #include "user.h"
extern "C" {
#include <stdarg.h> #include <stdarg.h>
#include "fmt.h"
static void
printint(void (*putch) (void*, char), void *putarg,
s64 xx, int base, int sgn)
{
const static char digits[] = "0123456789ABCDEF";
char buf[21];
int i, neg;
s64 x;
neg = 0;
if(sgn && xx < 0){
neg = 1;
x = -xx;
} else {
x = xx;
}
i = 0;
do{
buf[i++] = digits[x % base];
}while((x /= base) != 0);
if(neg)
buf[i++] = '-';
while(--i >= 0)
putch(putarg, buf[i]);
}
// Only understands %d, %x, %p, %s.
void
vprintfmt(void (*putch) (void*, char), void *putarg,
const char *fmt, va_list ap)
{
const char *s;
int c, i, state;
state = 0;
for(i = 0; fmt[i]; i++){
c = fmt[i] & 0xff;
if(state == 0){
if(c == '%'){
state = '%';
} else {
putch(putarg, c);
}
} else if(state == '%'){
if(c == 'd'){
printint(putch, putarg, va_arg(ap, u32), 10, 1);
} else if(c == 'x') {
printint(putch, putarg, va_arg(ap, u32), 16, 0);
} else if(c == 'l') {
state = 'l';
continue;
} else if(c == 's'){
s = (const char*) va_arg(ap, const char*);
if(s == 0)
s = "(null)";
while(*s != 0){
putch(putarg, *s);
s++;
}
} else if(c == 'c'){
putch(putarg, va_arg(ap, u32));
} else if(c == '%'){
putch(putarg, c);
} else {
// Unknown % sequence. Print it to draw attention.
putch(putarg, '%');
putch(putarg, c);
}
state = 0;
} else if(state == 'l') {
if(c == 'x') {
printint(putch, putarg, va_arg(ap, u64), 16, 0);
}
else if(c == 'u') {
printint(putch, putarg, va_arg(ap, u64), 10, 0);
}
else {
// Unknown % sequence. Print it to draw attention.
putch(putarg, '%');
putch(putarg, c);
}
state = 0;
}
}
} }
// Print to the given fd. // Print to the given fd.
static void static void
writec(void *arg, char c) writec(int c, void *arg)
{ {
int fd = (int) (u64) arg; int fd = (int) (u64) arg;
write(fd, &c, 1); write(fd, &c, 1);
...@@ -117,7 +31,7 @@ struct bufstate { ...@@ -117,7 +31,7 @@ struct bufstate {
}; };
static void static void
writebuf(void *arg, char c) writebuf(int c, void *arg)
{ {
struct bufstate *bs = (bufstate*) arg; struct bufstate *bs = (bufstate*) arg;
if (bs->p < bs->e) { if (bs->p < bs->e) {
......
...@@ -92,7 +92,7 @@ safestrcpy(char *s, const char *t, u32 n) ...@@ -92,7 +92,7 @@ safestrcpy(char *s, const char *t, u32 n)
return os; return os;
} }
int unsigned int
strlen(const char *s) strlen(const char *s)
{ {
int n; int n;
......
...@@ -79,12 +79,16 @@ ssize_t ...@@ -79,12 +79,16 @@ ssize_t
sys_pread(int fd, void *ubuf, size_t count, off_t offset) sys_pread(int fd, void *ubuf, size_t count, off_t offset)
{ {
struct file *f; struct file *f;
uptr i = (uptr)ubuf;
int r; int r;
if(fd < 0 || fd >= NOFILE || (f=myproc()->ofile[fd]) == 0) if(fd < 0 || fd >= NOFILE || (f=myproc()->ofile[fd]) == 0)
return -1; return -1;
// XXX(sbw) assuming ubuf is ok for(uptr va = PGROUNDDOWN(i); va < i+count; va = va + PGSIZE)
if(pagefault(myproc()->vmap, va, 0) < 0)
return -1;
if(f->type == file::FD_INODE){ if(f->type == file::FD_INODE){
ilock(f->ip, 0); ilock(f->ip, 0);
if(f->ip->type == 0) if(f->ip->type == 0)
......
BEGIN_DECLS
struct stat; struct stat;
// system calls // system calls
extern "C" {
int fork(int); int fork(int);
int exit(void) __attribute__((noreturn)); int exit(void) __attribute__((noreturn));
int wait(void); int wait(void);
...@@ -28,7 +28,6 @@ int unmap(void *addr, int len); ...@@ -28,7 +28,6 @@ int unmap(void *addr, int len);
void halt(void); void halt(void);
ssize_t pread(int, void*, size_t, off_t); ssize_t pread(int, void*, size_t, off_t);
int kernlet(int, size_t, off_t); int kernlet(int, size_t, off_t);
}
// ulib.c // ulib.c
int stat(char*, struct stat*); int stat(char*, struct stat*);
...@@ -46,11 +45,10 @@ void free(void*); ...@@ -46,11 +45,10 @@ void free(void*);
int atoi(const char*); int atoi(const char*);
// uthread.S // uthread.S
extern "C" {
int forkt(void *sp, void *pc, void *arg); int forkt(void *sp, void *pc, void *arg);
}
// printf.c // printf.c
void printf(int, const char*, ...); void printf(int, const char*, ...);
void snprintf(char *buf, unsigned int n, const char *fmt, ...); void snprintf(char *buf, unsigned int n, const char *fmt, ...);
void die(const char* errstr, ...) __attribute__((noreturn)); void die(const char* errstr, ...) __attribute__((noreturn));
END_DECLS
...@@ -1544,6 +1544,50 @@ unopentest(void) ...@@ -1544,6 +1544,50 @@ unopentest(void)
printf(stdout, "concurrent unlink/open ok\n"); printf(stdout, "concurrent unlink/open ok\n");
} }
void
preads(void)
{
static const int fsize = (64 << 10);
static const int bsize = 4096;
static const int nprocs = 4;
static const int iters = 100;
static char buf[bsize];
int fd;
int pid;
printf(1, "concurrent preads\n");
fd = open("preads.x", O_CREATE|O_RDWR);
if (fd < 0)
die("preads: open failed");
for (int i = 0; i < fsize/bsize; i++)
if (write(fd, buf, bsize) != bsize)
die("preads: write failed");
close(fd);
for (int i = 0; i < nprocs; i++) {
pid = fork(0);
if (pid < 0)
die("preads: fork failed");
if (pid == 0)
break;
}
for (int k = 0; k < iters; k++) {
fd = open("preads.x", O_RDONLY);
for (int i = 0; i < fsize; i+=bsize)
if (pread(fd, buf, bsize, i) != bsize)
die("preads: pread failed");
close(fd);
}
if (pid == 0)
exit();
printf(1, "concurrent preads OK\n");
}
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
...@@ -1567,6 +1611,7 @@ main(int argc, char *argv[]) ...@@ -1567,6 +1611,7 @@ main(int argc, char *argv[])
writetest(); writetest();
writetest1(); writetest1();
createtest(); createtest();
preads();
// mem(); // mem();
pipe1(); pipe1();
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论