提交 ebba3c91 创建 作者: Robert Morris's avatar Robert Morris

pipe.c uses condvars; that was the last use of sleep/wakeup

list of sleepers per condvar
上级 ba45ab30
...@@ -12,6 +12,7 @@ void ...@@ -12,6 +12,7 @@ void
initcondvar(struct condvar *cv, char *n) initcondvar(struct condvar *cv, char *n)
{ {
initlock(&cv->lock, n); initlock(&cv->lock, n);
cv->waiters = 0;
} }
void void
...@@ -28,10 +29,11 @@ cv_sleep(struct condvar *cv, struct spinlock *lk) ...@@ -28,10 +29,11 @@ cv_sleep(struct condvar *cv, struct spinlock *lk)
release(lk); release(lk);
if (cv->waiters != 0) if(proc->cv_next)
panic("cv_sleep\n"); panic("cv_sleep cv_next");
cv->waiters = proc; // XXX should be queue proc->cv_next = cv->waiters;
cv->waiters = proc;
acquire(&proc->lock); acquire(&proc->lock);
...@@ -47,13 +49,18 @@ cv_sleep(struct condvar *cv, struct spinlock *lk) ...@@ -47,13 +49,18 @@ cv_sleep(struct condvar *cv, struct spinlock *lk)
acquire(lk); acquire(lk);
} }
// Wake up all processes sleeping on this condvar.
void void
cv_wakeup(struct condvar *cv) cv_wakeup(struct condvar *cv)
{ {
acquire(&cv->lock); acquire(&cv->lock);
if (cv->waiters != 0) { while(cv->waiters) {
if(cv->waiters->state != SLEEPING)
panic("cv_wakeup");
struct proc *nxt = cv->waiters->cv_next;
cv->waiters->cv_next = 0;
addrun(cv->waiters); addrun(cv->waiters);
cv->waiters = 0; cv->waiters = nxt;
} }
release(&cv->lock); release(&cv->lock);
} }
...@@ -115,8 +115,6 @@ void sched(void); ...@@ -115,8 +115,6 @@ void sched(void);
void userinit(void); void userinit(void);
int wait(void); int wait(void);
void yield(void); void yield(void);
void wakeup(void*);
void sleep(void*, struct spinlock*);
// swtch.S // swtch.S
void swtch(struct context**, struct context*); void swtch(struct context**, struct context*);
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
struct pipe { struct pipe {
struct spinlock lock; struct spinlock lock;
struct condvar cv;
char data[PIPESIZE]; char data[PIPESIZE];
uint nread; // number of bytes read uint nread; // number of bytes read
uint nwrite; // number of bytes written uint nwrite; // number of bytes written
...@@ -36,6 +37,7 @@ pipealloc(struct file **f0, struct file **f1) ...@@ -36,6 +37,7 @@ pipealloc(struct file **f0, struct file **f1)
p->nwrite = 0; p->nwrite = 0;
p->nread = 0; p->nread = 0;
initlock(&p->lock, "pipe"); initlock(&p->lock, "pipe");
initcondvar(&p->cv, "pipe");
(*f0)->type = FD_PIPE; (*f0)->type = FD_PIPE;
(*f0)->readable = 1; (*f0)->readable = 1;
(*f0)->writable = 0; (*f0)->writable = 0;
...@@ -63,11 +65,10 @@ pipeclose(struct pipe *p, int writable) ...@@ -63,11 +65,10 @@ pipeclose(struct pipe *p, int writable)
acquire(&p->lock); acquire(&p->lock);
if(writable){ if(writable){
p->writeopen = 0; p->writeopen = 0;
wakeup(&p->nread);
} else { } else {
p->readopen = 0; p->readopen = 0;
wakeup(&p->nwrite);
} }
cv_wakeup(&p->cv);
if(p->readopen == 0 && p->writeopen == 0){ if(p->readopen == 0 && p->writeopen == 0){
release(&p->lock); release(&p->lock);
kfree((char*)p); kfree((char*)p);
...@@ -88,12 +89,12 @@ pipewrite(struct pipe *p, char *addr, int n) ...@@ -88,12 +89,12 @@ pipewrite(struct pipe *p, char *addr, int n)
release(&p->lock); release(&p->lock);
return -1; return -1;
} }
wakeup(&p->nread); cv_wakeup(&p->cv);
sleep(&p->nwrite, &p->lock); //DOC: pipewrite-sleep cv_sleep(&p->cv, &p->lock); //DOC: pipewrite-sleep
} }
p->data[p->nwrite++ % PIPESIZE] = addr[i]; p->data[p->nwrite++ % PIPESIZE] = addr[i];
} }
wakeup(&p->nread); //DOC: pipewrite-wakeup1 cv_wakeup(&p->cv); //DOC: pipewrite-wakeup1
release(&p->lock); release(&p->lock);
return n; return n;
} }
...@@ -109,14 +110,14 @@ piperead(struct pipe *p, char *addr, int n) ...@@ -109,14 +110,14 @@ piperead(struct pipe *p, char *addr, int n)
release(&p->lock); release(&p->lock);
return -1; return -1;
} }
sleep(&p->nread, &p->lock); //DOC: piperead-sleep cv_sleep(&p->cv, &p->lock); //DOC: piperead-sleep
} }
for(i = 0; i < n; i++){ //DOC: piperead-copy for(i = 0; i < n; i++){ //DOC: piperead-copy
if(p->nread == p->nwrite) if(p->nread == p->nwrite)
break; break;
addr[i] = p->data[p->nread++ % PIPESIZE]; addr[i] = p->data[p->nread++ % PIPESIZE];
} }
wakeup(&p->nwrite); //DOC: piperead-wakeup cv_wakeup(&p->cv); //DOC: piperead-wakeup
release(&p->lock); release(&p->lock);
return i; return i;
} }
...@@ -621,19 +621,3 @@ procdumpall(void) ...@@ -621,19 +621,3 @@ procdumpall(void)
procdump(c); procdump(c);
} }
} }
//// dead code
// Atomically release lock and sleep on chan.
// Reacquires lock when awakened.
void
sleep(void *chan, struct spinlock *lk)
{
panic("sleep");
}
// Wake up all processes sleeping on chan.
void
wakeup(void *chan)
{
}
...@@ -75,7 +75,7 @@ struct proc { ...@@ -75,7 +75,7 @@ struct proc {
struct proc *parent; // Parent process struct proc *parent; // Parent process
struct trapframe *tf; // Trap frame for current syscall struct trapframe *tf; // Trap frame for current syscall
struct context *context; // swtch() here to run process struct context *context; // swtch() here to run process
void *chan; // If non-zero, sleeping on chan struct proc *cv_next; // Linked list of processes waiting for condvar
int killed; // If non-zero, have been killed int killed; // If non-zero, have been killed
struct file *ofile[NOFILE]; // Open files struct file *ofile[NOFILE]; // Open files
struct inode *cwd; // Current directory struct inode *cwd; // Current directory
......
...@@ -1477,7 +1477,7 @@ main(int argc, char *argv[]) ...@@ -1477,7 +1477,7 @@ main(int argc, char *argv[])
bigargtest(); bigargtest();
bsstest(); bsstest();
sbrktest(); // sbrktest();
validatetest(); validatetest();
opentest(); opentest();
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论