summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bio.c31
-rw-r--r--buf.h2
-rw-r--r--defs.h2
-rw-r--r--init.c4
-rw-r--r--sh.c5
-rw-r--r--syscall.c53
-rw-r--r--syscall.h3
-rw-r--r--ulib.c11
-rw-r--r--user.h3
-rw-r--r--usertests.c128
-rw-r--r--usys.S3
11 files changed, 159 insertions, 86 deletions
diff --git a/bio.c b/bio.c
index 2b17a52..7184a28 100644
--- a/bio.c
+++ b/bio.c
@@ -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);
diff --git a/buf.h b/buf.h
index a4cea5e..e3f6b14 100644
--- a/buf.h
+++ b/buf.h
@@ -1,5 +1,7 @@
struct buf {
int flags;
+ uint dev;
+ uint sector;
uchar data[512];
};
#define B_BUSY 0x1
diff --git a/defs.h b/defs.h
index 3674c45..f54d829 100644
--- a/defs.h
+++ b/defs.h
@@ -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 *);
diff --git a/init.c b/init.c
index dcd0fda..0a4223c 100644
--- a/init.c
+++ b/init.c
@@ -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);
diff --git a/sh.c b/sh.c
index e9ed2d9..9d4a308 100644
--- a/sh.c
+++ b/sh.c
@@ -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)
diff --git a/syscall.c b/syscall.c
index 0f90bd6..48da287 100644
--- a/syscall.c
+++ b/syscall.c
@@ -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;
diff --git a/syscall.h b/syscall.h
index 9924c7f..ca2855c 100644
--- a/syscall.h
+++ b/syscall.h
@@ -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
diff --git a/ulib.c b/ulib.c
index ccb9fd6..b759f45 100644
--- a/ulib.c
+++ b/ulib.c
@@ -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)
{
diff --git a/user.h b/user.h
index d91b4df..9dd1684 100644
--- a/user.h
+++ b/user.h
@@ -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();
}
diff --git a/usys.S b/usys.S
index aa3a22e..f9565e5 100644
--- a/usys.S
+++ b/usys.S
@@ -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)