Comment on page
How unix pipes work?
int pipewrite(struct pipe *pi, uint64 addr, int n)
{
int I;
char ch;
struct proc *pr = myproc();
acquire(&pi->lock);
for(I = 0; I < n; I++){
while(pi->nwrite == pi->nread + PIPESIZE){ *//DOC: pipewrite-full*
if(pi->readopen == 0 || myproc()->killed){
release(&pi->lock);
return -1;
}
wakeup(&pi->nread);
sleep(&pi->nwrite, &pi->lock);
}
if(copyin(pr->pagetable, &ch, addr + I, 1) == -1)
break;
pi->data[pi->nwrite++ % PIPESIZE] = ch;
}
wakeup(&pi->nread);
release(&pi->lock);
return n;
}
int
piperead(struct pipe *pi, uint64 addr, int n)
{
int i;
struct proc *pr = myproc();
char ch;
acquire(&pi->lock);
while(pi->nread == pi->nwrite && pi->writeopen){ *//DOC: pipe-empty*
if(myproc()->killed){
release(&pi->lock);
return -1;
}
sleep(&pi->nread, &pi->lock); *//DOC: piperead-sleep*
}
for(I = 0; I < n; I++){ *//DOC: piperead-copy*
if(pi->nread == pi->nwrite)
break;
ch = pi->data[pi->nread++ % PIPESIZE];
if(copyout(pr->pagetable, addr + i, &ch, 1) == -1)
break;
}
wakeup(&pi->nwrite); *//DOC: piperead-wakeup*
release(&pi->lock);
return i;
}
- Pipe buffer wraps around.
- a full buffer
(nwrite == nread+PIPESIZE)
- an empty buffer
(nwrite == nread)
Pipewrite
wakes up reader if buffer is full, or written is down.Piperead
sleep if no more data. Or read data from pipe, copy out to address. Then wake up the write channel.

Add more code.
- 1.In
piperead
, why we wake up write first, then releasepi->lock
? - 2.Why
piperead
does not go back to sleep after reading? Why there is no loop forpiperead
? Or is there an outside loop?