fix getblk to actually lock the block

no more cons_put system calls
usertests tests two processes writing files
This commit is contained in:
rtm 2006-08-12 11:38:57 +00:00
parent 1f544842ce
commit 4357207237
11 changed files with 159 additions and 86 deletions

31
bio.c
View file

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

2
buf.h
View file

@ -1,5 +1,7 @@
struct buf {
int flags;
uint dev;
uint sector;
uchar data[512];
};
#define B_BUSY 0x1

2
defs.h
View file

@ -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 *);

4
init.c
View file

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

5
sh.c
View file

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

View file

@ -214,38 +214,6 @@ sys_kill(void)
return proc_kill(pid);
}
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)
{
@ -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;

View file

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

11
ulib.c
View file

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

3
user.h
View file

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

View file

@ -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();
}

3
usys.S
View file

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