From 3c0a25fc4383140b3f8bf83f5eef4cbb14062e94 Mon Sep 17 00:00:00 2001 From: Robert Morris Date: Tue, 2 Jan 2024 10:04:23 -0500 Subject: x --- .gitignore | 2 +- grade-lab-lock | 4 ++ kernel/defs.h | 8 ++++ user/bcachetest.c | 129 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ user/user.h | 6 +++ 5 files changed, 148 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index d036a8b..11d0677 100644 --- a/.gitignore +++ b/.gitignore @@ -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 -- cgit v1.2.3