diff options
-rw-r--r-- | bio.c | 31 | ||||
-rw-r--r-- | buf.h | 2 | ||||
-rw-r--r-- | defs.h | 2 | ||||
-rw-r--r-- | init.c | 4 | ||||
-rw-r--r-- | sh.c | 5 | ||||
-rw-r--r-- | syscall.c | 53 | ||||
-rw-r--r-- | syscall.h | 3 | ||||
-rw-r--r-- | ulib.c | 11 | ||||
-rw-r--r-- | user.h | 3 | ||||
-rw-r--r-- | usertests.c | 128 | ||||
-rw-r--r-- | usys.S | 3 |
11 files changed, 159 insertions, 86 deletions
@@ -17,24 +17,31 @@ binit(void) } struct buf * -getblk() +getblk(uint dev, uint sector) { - int i; + struct buf *b; acquire(&buf_table_lock); - // XXX need to lock the block even if not caching, to - // avoid read modify write problems. - while(1){ - for(i = 0; i < NBUF; i++){ - if((buf[i].flags & B_BUSY) == 0){ - buf[i].flags |= B_BUSY; - release(&buf_table_lock); - return buf + i; + for(b = buf; b < buf+NBUF; b++) + if((b->flags & B_BUSY) && b->dev == dev && b->sector) + break; + + if(b < buf+NBUF){ + sleep(buf, &buf_table_lock); + } else { + for(b = buf; b < buf+NBUF; b++){ + if((b->flags & B_BUSY) == 0){ + b->flags |= B_BUSY; + b->dev = dev; + b->sector = sector; + release(&buf_table_lock); + return b; + } } + panic("getblk: no buffers"); } - sleep(buf, &buf_table_lock); } } @@ -45,7 +52,7 @@ bread(uint dev, uint sector) struct buf *b; extern struct spinlock ide_lock; - b = getblk(); + b = getblk(dev, sector); acquire(&ide_lock); c = ide_start_rw(dev & 0xff, sector, b->data, 1, 1); @@ -1,5 +1,7 @@ struct buf { int flags; + uint dev; + uint sector; uchar data[512]; }; #define B_BUSY 0x1 @@ -104,7 +104,7 @@ int ide_finish(void *); // bio.c void binit(void); struct buf; -struct buf *getblk(void); +struct buf * getblk(uint dev, uint sector); struct buf *bread(uint, uint); void bwrite(uint, struct buf *, uint); void brelse(struct buf *); @@ -17,10 +17,10 @@ main(void) open("console", 1); open("console", 1); - write(1, "init...\n", 8); + puts("init...\n"); while(1){ - write(1, "running sh...\n", 14); + puts("running sh...\n"); pid = fork(); if(pid == 0){ exec("sh", sh_args); @@ -12,7 +12,7 @@ main(void) int pid; while(1){ - write(1, "$ ", 2); + puts("$ "); gets(buf, sizeof(buf)); if(buf[0] == '\0') continue; @@ -21,8 +21,7 @@ main(void) args[0] = buf; args[1] = 0; exec(buf, args); - write(1, buf, strlen(buf)); - write(1, ": not found\n", 12); + printf(1, "%s: not found\n", buf); exit(); } if(pid > 0) @@ -215,38 +215,6 @@ sys_kill(void) } int -sys_cons_putc(void) -{ - int c; - char buf[2]; - - if(fetcharg(0, &c) < 0) - return -1; - buf[0] = c; - buf[1] = 0; - cprintf("%s", buf); - return 0; -} - -int -sys_cons_puts(void) -{ - char buf[256]; - int i; - uint addr; - struct proc *cp = curproc[cpu()]; - - if(fetcharg(0, &addr) < 0) - return -1; - for(i=0; i<sizeof buf-1 && fetchbyte(cp, addr+i, &buf[i]) >= 0; i++) - if(buf[i] == 0) - break; - buf[i] = 0; - cprintf("%s", buf); - return 0; -} - -int sys_open(void) { struct proc *cp = curproc[cpu()]; @@ -525,18 +493,6 @@ sys_block(void) return 0; } -int -sys_panic(void) -{ - struct proc *p = curproc[cpu()]; - uint addr; - - if(fetcharg(0, &addr) < 0) - return -1; - panic(p->mem + addr); - return 0; -} - void syscall(void) { @@ -554,9 +510,6 @@ syscall(void) case SYS_wait: ret = sys_wait(); break; - case SYS_cons_putc: - ret = sys_cons_putc(); - break; case SYS_pipe: ret = sys_pipe(); break; @@ -575,12 +528,6 @@ syscall(void) case SYS_kill: ret = sys_kill(); break; - case SYS_panic: - ret = sys_panic(); - break; - case SYS_cons_puts: - ret = sys_cons_puts(); - break; case SYS_exec: ret = sys_exec(); break; @@ -1,15 +1,12 @@ #define SYS_fork 1 #define SYS_exit 2 #define SYS_wait 3 -#define SYS_cons_putc 4 #define SYS_pipe 5 #define SYS_write 6 #define SYS_read 7 #define SYS_close 8 #define SYS_block 9 #define SYS_kill 10 -#define SYS_panic 11 -#define SYS_cons_puts 12 #define SYS_exec 13 #define SYS_open 14 #define SYS_mknod 15 @@ -26,6 +26,17 @@ strlen(char *s) return n; } +void * +memset(void *dst, int c, unsigned int n) +{ + char *d = (char *) dst; + + while(n-- > 0) + *d++ = c; + + return dst; +} + char * gets(char *buf, int max) { @@ -14,9 +14,12 @@ int exec(char *, char **); int open(char *, int); int mknod (char*,short,short,short); int unlink (char*); +struct stat; int fstat (int fd, struct stat *stat); + int puts(char*); char* strcpy(char*, char*); void printf(int fd, char *fmt, ...); char *gets(char *, int max); unsigned int strlen(char *); +void * memset(void *dst, int c, unsigned int n); diff --git a/usertests.c b/usertests.c index cba362f..12fa6f8 100644 --- a/usertests.c +++ b/usertests.c @@ -1,4 +1,5 @@ #include "user.h" +#include "fcntl.h" char buf[2048]; @@ -18,7 +19,7 @@ pipe1(void) for(i = 0; i < 1033; i++) buf[i] = seq++; if(write(fds[1], buf, 1033) != 1033){ - panic("pipe1 oops 1\n"); + printf(1, "pipe1 oops 1\n"); exit(); } } @@ -30,7 +31,7 @@ pipe1(void) while((n = read(fds[0], buf, cc)) > 0){ for(i = 0; i < n; i++){ if((buf[i] & 0xff) != (seq++ & 0xff)){ - panic("pipe1 oops 2\n"); + printf(1, "pipe1 oops 2\n"); return; } } @@ -40,7 +41,7 @@ pipe1(void) cc = sizeof(buf); } if(total != 5 * 1033) - panic("pipe1 oops 3\n"); + printf(1, "pipe1 oops 3\n"); close(fds[0]); wait(); } @@ -69,7 +70,7 @@ preempt(void) if(pid3 == 0){ close(pfds[0]); if(write(pfds[1], "x", 1) != 1) - panic("preempt write error"); + printf(1, "preempt write error"); close(pfds[1]); for(;;) ; @@ -77,7 +78,7 @@ preempt(void) close(pfds[1]); if(read(pfds[0], buf, sizeof(buf)) != 1){ - panic("preempt read error"); + printf(1, "preempt read error"); return; } close(pfds[0]); @@ -99,12 +100,12 @@ exitwait(void) for(i = 0; i < 100; i++){ pid = fork(); if(pid < 0){ - panic("fork failed\n"); + printf(1, "fork failed\n"); return; } if(pid){ if(wait() != pid){ - panic("wait wrong pid\n"); + printf(1, "wait wrong pid\n"); return; } } else { @@ -114,15 +115,124 @@ exitwait(void) puts("exitwait ok\n"); } +// two processes write to the same file descriptor +// is the offset shared? does inode locking work? +void +sharedfd() +{ + int fd, pid, i, n, nc, np; + char buf[10]; + + unlink("sharedfd"); + fd = open("sharedfd", O_CREATE|O_RDWR); + if(fd < 0){ + printf(1, "usertests: cannot open sharedfd for writing"); + return; + } + pid = fork(); + memset(buf, pid==0?'c':'p', sizeof(buf)); + for(i = 0; i < 100; i++){ + if(write(fd, buf, sizeof(buf)) != sizeof(buf)){ + printf(1, "usertests: write sharedfd failed\n"); + break; + } + } + if(pid == 0) + exit(); + else + wait(); + close(fd); + fd = open("sharedfd", 0); + if(fd < 0){ + printf(1, "usertests: cannot open sharedfd for reading\n"); + return; + } + nc = np = 0; + while((n = read(fd, buf, sizeof(buf))) > 0){ + for(i = 0; i < sizeof(buf); i++){ + if(buf[i] == 'c') + nc++; + if(buf[i] == 'p') + np++; + } + } + close(fd); + if(nc == 1000 && np == 1000) + printf(1, "sharedfd ok\n"); + else + printf(1, "sharedfd oops %d %d\n", nc, np); +} + +// two processes write two different files at the same +// time, to test block allocation. +void +twofiles() +{ + int fd, pid, i, j, n, total; + char *fname; + + unlink("f1"); + unlink("f2"); + + pid = fork(); + if(pid < 0){ + puts("fork failed\n"); + return; + } + + fname = pid ? "f1" : "f2"; + fd = open(fname, O_CREATE | O_RDWR); + if(fd < 0){ + puts("create failed\n"); + exit(); + } + + memset(buf, pid?'p':'c', 512); + for(i = 0; i < 12; i++){ + if((n = write(fd, buf, 500)) != 500){ + printf(1, "write failed %d\n", n); + exit(); + } + } + close(fd); + if(pid) + wait(); + else + exit(); + + for(i = 0; i < 2; i++){ + fd = open(i?"f1":"f2", 0); + total = 0; + while((n = read(fd, buf, sizeof(buf))) > 0){ + for(j = 0; j < n; j++){ + if(buf[j] != (i?'p':'c')){ + puts("wrong char\n"); + exit(); + } + } + total += n; + } + close(fd); + if(total != 12*500){ + printf(1, "wrong length %d\n", total); + exit(); + } + } + + puts("twofiles ok\n"); +} + int main(int argc, char *argv[]) { puts("usertests starting\n"); + twofiles(); + sharedfd(); pipe1(); preempt(); exitwait(); - panic("usertests succeeded"); - return 0; + puts("usertests finished\n"); + exit(); } @@ -11,15 +11,12 @@ STUB(fork) STUB(exit) STUB(wait) -STUB(cons_putc) STUB(pipe) STUB(read) STUB(write) STUB(close) STUB(block) STUB(kill) -STUB(panic) -STUB(cons_puts) STUB(exec) STUB(open) STUB(mknod) |