summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Morris <[email protected]>2024-01-02 10:04:23 -0500
committerRobert Morris <[email protected]>2024-01-02 10:04:23 -0500
commit3c0a25fc4383140b3f8bf83f5eef4cbb14062e94 (patch)
tree96b8c9987973ece5798f45534e0bd6b954fdff9d
parent3808f903625f42f58aa95e43e3caca3efaa4d118 (diff)
downloadxv6-labs-3c0a25fc4383140b3f8bf83f5eef4cbb14062e94.tar.gz
xv6-labs-3c0a25fc4383140b3f8bf83f5eef4cbb14062e94.tar.bz2
xv6-labs-3c0a25fc4383140b3f8bf83f5eef4cbb14062e94.zip
x
-rw-r--r--.gitignore2
-rwxr-xr-xgrade-lab-lock4
-rw-r--r--kernel/defs.h8
-rw-r--r--user/bcachetest.c129
-rw-r--r--user/user.h6
5 files changed, 148 insertions, 1 deletions
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