[xv6]:pipe

直接看代码

  • pipe结构

    1
    2
    3
    4
    5
    6
    7
    8
    struct pipe {
    struct spinlock lock;
    char data[PIPESIZE];
    uint nread; // number of bytes read
    uint nwrite; // number of bytes written
    int readopen; // read fd is still open
    int writeopen; // write fd is still open
    };
    • pipe中的data使用环型计数
    • nread以及nwrite不使用环型计数
    • 缓冲区满: nwrite == nread + PIPESIZE
    • 缓冲区空: nwrite == n
  • pipewrite()

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    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++){
    // 缓冲区满, 唤醒那些reader进程, writer进程陷入sleep
    while(pi->nwrite == pi->nread + PIPESIZE){ //DOC: pipewrite-full
    if(pi->readopen == 0 || pr->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 i;
    }
  • piperead()

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    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(pr->killed){
    release(&pi->lock);
    return -1;
    }
    sleep(&pi->nread, &pi->lock); //DOC: piperead-sleep
    }
    // 每字节读取数据到addr
    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;
    }
    // 读取完毕之后唤醒writer进程
    wakeup(&pi->nwrite); //DOC: piperead-wakeup
    release(&pi->lock);
    return i;
    }

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!