diff options
author | rtm <rtm> | 2006-07-12 01:48:35 +0000 |
---|---|---|
committer | rtm <rtm> | 2006-07-12 01:48:35 +0000 |
commit | 4e8f237be819424f922399f8d121d9867b675541 (patch) | |
tree | 53459cfde9630b3ae0d2d46d0ce3d4c1ac423944 /pipe.c | |
parent | b41b38d0da0854f3fa92967b70180ea1156154d4 (diff) | |
download | xv6-labs-4e8f237be819424f922399f8d121d9867b675541.tar.gz xv6-labs-4e8f237be819424f922399f8d121d9867b675541.tar.bz2 xv6-labs-4e8f237be819424f922399f8d121d9867b675541.zip |
no more big kernel lock
succeeds at usertests.c pipe test
Diffstat (limited to 'pipe.c')
-rw-r--r-- | pipe.c | 10 |
1 files changed, 10 insertions, 0 deletions
@@ -5,6 +5,7 @@ #include "proc.h" #include "defs.h" #include "fd.h" +#include "spinlock.h" #define PIPESIZE 512 @@ -13,6 +14,7 @@ struct pipe { int writeopen; // write fd is still open int writep; // next index to write int readp; // next index to read + struct spinlock lock; char data[PIPESIZE]; }; @@ -32,6 +34,7 @@ pipe_alloc(struct fd **fd1, struct fd **fd2) p->writeopen = 1; p->writep = 0; p->readp = 0; + memset(&p->lock, 0, sizeof(p->lock)); (*fd1)->type = FD_PIPE; (*fd1)->readable = 1; (*fd1)->writeable = 0; @@ -74,16 +77,21 @@ pipe_write(struct pipe *p, char *addr, int n) { int i; + acquire(&p->lock); + for(i = 0; i < n; i++){ while(((p->writep + 1) % PIPESIZE) == p->readp){ if(p->readopen == 0) return -1; + release(&p->lock); wakeup(&p->readp); sleep(&p->writep); + acquire(&p->lock); } p->data[p->writep] = addr[i]; p->writep = (p->writep + 1) % PIPESIZE; } + release(&p->lock); wakeup(&p->readp); return i; } @@ -99,12 +107,14 @@ pipe_read(struct pipe *p, char *addr, int n) sleep(&p->readp); } + acquire(&p->lock); for(i = 0; i < n; i++){ if(p->readp == p->writep) break; addr[i] = p->data[p->readp]; p->readp = (p->readp + 1) % PIPESIZE; } + release(&p->lock); wakeup(&p->writep); return i; } |