diff options
| -rw-r--r-- | .gitignore | 2 | ||||
| -rwxr-xr-x | grade-lab-lock | 4 | ||||
| -rw-r--r-- | kernel/defs.h | 8 | ||||
| -rw-r--r-- | user/bcachetest.c | 129 | ||||
| -rw-r--r-- | user/user.h | 6 | 
5 files changed, 148 insertions, 1 deletions
| @@ -11,7 +11,7 @@ entryother  initcode  initcode.out  kernelmemfs -mkfs +mkfs/mkfs  kernel/kernel  user/usys.S  .gdbinit diff --git a/grade-lab-lock b/grade-lab-lock index 770d676..fa90fef 100755 --- a/grade-lab-lock +++ b/grade-lab-lock @@ -44,6 +44,10 @@ def test_bcachetest_test0():  def test_bcachetest_test1():      r.match('^test1 OK$') +@test(10, "bcachetest: test2", parent=test_bcachetest) +def test_bcachetest_test2(): +    r.match('^test2 OK$') +  @test(19, "usertests")  def test_usertests():      r.run_qemu(shell_script([ diff --git a/kernel/defs.h b/kernel/defs.h index c6fef8c..859fc41 100644 --- a/kernel/defs.h +++ b/kernel/defs.h @@ -1,3 +1,7 @@ +#ifdef LAB_MMAP +typedef unsigned long size_t; +typedef long int off_t; +#endif  struct buf;  struct context;  struct file; @@ -121,7 +125,9 @@ void            initlock(struct spinlock*, char*);  void            release(struct spinlock*);  void            push_off(void);  void            pop_off(void); +#if defined(LAB_LOCK) || defined(LAB_NET)  int             atomic_read4(int *addr); +#endif  #ifdef LAB_LOCK  void            freelock(struct spinlock*);  #endif @@ -204,12 +210,14 @@ int             copyin_new(pagetable_t, char *, uint64, uint64);  int             copyinstr_new(pagetable_t, char *, uint64, uint64);  #endif +#ifdef LAB_LOCK  // stats.c  void            statsinit(void);  void            statsinc(void);  // sprintf.c  int             snprintf(char*, int, char*, ...); +#endif  #ifdef KCSAN  void            kcsaninit(); diff --git a/user/bcachetest.c b/user/bcachetest.c index 5dc46ef..ccf7516 100644 --- a/user/bcachetest.c +++ b/user/bcachetest.c @@ -8,6 +8,7 @@  void test0();  void test1(); +void test2();  #define SZ 4096  char buf[SZ]; @@ -17,6 +18,7 @@ main(int argc, char *argv[])  {    test0();    test1(); +  test2();    exit(0);  } @@ -187,3 +189,130 @@ void test1()    }    printf("test1 OK\n");  } + +// +// test concurrent creates. +// +void +test2() +{ +  int nc = 4; +  char file[16]; + +  printf("start test2\n"); +   +  mkdir("d2"); + +  file[0] = 'd'; +  file[1] = '2'; +  file[2] = '/'; + +  // remove any stale existing files. +  for(int i = 0; i < 50; i++){ +    for(int ci = 0; ci < nc; ci++){ +      file[3] = 'a' + ci; +      file[4] = '0' + i; +      file[5] = '\0'; +      unlink(file); +    } +  } + +  int pids[nc]; +  for(int ci = 0; ci < nc; ci++){ +    pids[ci] = fork(); +    if(pids[ci] < 0){ +      printf("test2: fork failed\n"); +      exit(1); +    } +    if(pids[ci] == 0){ +      char me = "abcdefghijklmnop"[ci]; +      int pid = getpid(); +      int nf = (ci == 0 ? 10 : 15); + +      // create nf files. +      for(int i = 0; i < nf; i++){ +        file[3] = me; +        file[4] = '0' + i; +        file[5] = '\0'; +        // printf("w %s\n", file); +        int fd = open(file, O_CREATE | O_RDWR); +        if(fd < 0){ +          printf("test2: create %s failed\n", file); +          exit(1); +        } +        int xx = (pid << 16) | i; +        for(int nw = 0; nw < 2; nw++){ +          // the sleep() increases the chance of simultaneous +          // calls to bget(). +          sleep(1); +          if(write(fd, &xx, sizeof(xx)) <= 0){ +            printf("test2: write %s failed\n", file); +            exit(1); +          } +        } +        close(fd); +      } + +      // read back the nf files. +      for(int i = 0; i < nf; i++){ +        file[3] = me; +        file[4] = '0' + i; +        file[5] = '\0'; +        // printf("r %s\n", file); +        int fd = open(file, O_RDWR); +        if(fd < 0){ +          printf("test2: open %s failed\n", file); +          exit(1); +        } +        int xx = (pid << 16) | i; +        for(int nr = 0; nr < 2; nr++){ +          int z = 0; +          sleep(1); +          int n = read(fd, &z, sizeof(z)); +          if(n != sizeof(z)){ +            printf("test2: read %s returned %d, expected %d\n", file, n, sizeof(z)); +            exit(1); +          } +          if(z != xx){ +            printf("test2: file %s contained %d, not %d\n", file, z, xx); +            exit(1); +          } +        } +        close(fd); +      } + +      // delete the nf files. +      for(int i = 0; i < nf; i++){ +        file[3] = me; +        file[4] = '0' + i; +        file[5] = '\0'; +        //printf("u %s\n", file); +        if(unlink(file) != 0){ +          printf("test2: unlink %s failed\n", file); +          exit(1); +        } +      } + +      exit(0); +    } +  } + +  int ok = 1; + +  for(int ci = 0; ci < nc; ci++){ +    int st = 0; +    int ret = wait(&st); +    if(ret <= 0){ +      printf("test2: wait() failed\n"); +      ok = 0; +    } +    if(st != 0) +      ok = 0; +  } +   +  if(ok){ +    printf("test2 OK\n"); +  } else { +    printf("test2 failed\n"); +  } +} diff --git a/user/user.h b/user/user.h index 16cf173..2d6ace6 100644 --- a/user/user.h +++ b/user/user.h @@ -1,3 +1,7 @@ +#ifdef LAB_MMAP +typedef unsigned long size_t; +typedef long int off_t; +#endif  struct stat;  // system calls @@ -47,4 +51,6 @@ void free(void*);  int atoi(const char*);  int memcmp(const void *, const void *, uint);  void *memcpy(void *, const void *, uint); +#ifdef LAB_LOCK  int statistics(void*, int); +#endif | 
