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)
- Pipewritewakes up reader if buffer is full, or written is down.
- Pipereadsleep if no more data. Or read data from pipe, copy out to address. Then wake up the write channel.
Flow

TODO
Add more code.
A few open questions:
- In - piperead, why we wake up write first, then release- pi->lock?
- Why - pipereaddoes not go back to sleep after reading? Why there is no loop for- piperead? Or is there an outside loop?
Last updated
Was this helpful?