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) | 
