root/pipe.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pipealloc
  2. pipeclose
  3. pipewrite
  4. piperead

   1 #include "types.h"
   2 #include "defs.h"
   3 #include "param.h"
   4 #include "mmu.h"
   5 #include "proc.h"
   6 #include "fs.h"
   7 #include "file.h"
   8 #include "spinlock.h"
   9 
  10 #define PIPESIZE 512
  11 
  12 struct pipe {
  13   struct spinlock lock;
  14   char data[PIPESIZE];
  15   uint nread;     // number of bytes read
  16   uint nwrite;    // number of bytes written
  17   int readopen;   // read fd is still open
  18   int writeopen;  // write fd is still open
  19 };
  20 
  21 int
  22 pipealloc(struct file **f0, struct file **f1)
  23 {
  24   struct pipe *p;
  25 
  26   p = 0;
  27   *f0 = *f1 = 0;
  28   if((*f0 = filealloc()) == 0 || (*f1 = filealloc()) == 0)
  29     goto bad;
  30   if((p = (struct pipe*)kalloc()) == 0)
  31     goto bad;
  32   p->readopen = 1;
  33   p->writeopen = 1;
  34   p->nwrite = 0;
  35   p->nread = 0;
  36   initlock(&p->lock, "pipe");
  37   (*f0)->type = FD_PIPE;
  38   (*f0)->readable = 1;
  39   (*f0)->writable = 0;
  40   (*f0)->pipe = p;
  41   (*f1)->type = FD_PIPE;
  42   (*f1)->readable = 0;
  43   (*f1)->writable = 1;
  44   (*f1)->pipe = p;
  45   return 0;
  46 
  47 //PAGEBREAK: 20
  48  bad:
  49   if(p)
  50     kfree((char*)p);
  51   if(*f0)
  52     fileclose(*f0);
  53   if(*f1)
  54     fileclose(*f1);
  55   return -1;
  56 }
  57 
  58 void
  59 pipeclose(struct pipe *p, int writable)
  60 {
  61   acquire(&p->lock);
  62   if(writable){
  63     p->writeopen = 0;
  64     wakeup(&p->nread);
  65   } else {
  66     p->readopen = 0;
  67     wakeup(&p->nwrite);
  68   }
  69   if(p->readopen == 0 && p->writeopen == 0){
  70     release(&p->lock);
  71     kfree((char*)p);
  72   } else
  73     release(&p->lock);
  74 }
  75 
  76 //PAGEBREAK: 40
  77 int
  78 pipewrite(struct pipe *p, char *addr, int n)
  79 {
  80   int i;
  81 
  82   acquire(&p->lock);
  83   for(i = 0; i < n; i++){
  84     while(p->nwrite == p->nread + PIPESIZE){  //DOC: pipewrite-full
  85       if(p->readopen == 0 || proc->killed){
  86         release(&p->lock);
  87         return -1;
  88       }
  89       wakeup(&p->nread);
  90       sleep(&p->nwrite, &p->lock);  //DOC: pipewrite-sleep
  91     }
  92     p->data[p->nwrite++ % PIPESIZE] = addr[i];
  93   }
  94   wakeup(&p->nread);  //DOC: pipewrite-wakeup1
  95   release(&p->lock);
  96   return n;
  97 }
  98 
  99 int
 100 piperead(struct pipe *p, char *addr, int n)
 101 {
 102   int i;
 103 
 104   acquire(&p->lock);
 105   while(p->nread == p->nwrite && p->writeopen){  //DOC: pipe-empty
 106     if(proc->killed){
 107       release(&p->lock);
 108       return -1;
 109     }
 110     sleep(&p->nread, &p->lock); //DOC: piperead-sleep
 111   }
 112   for(i = 0; i < n; i++){  //DOC: piperead-copy
 113     if(p->nread == p->nwrite)
 114       break;
 115     addr[i] = p->data[p->nread++ % PIPESIZE];
 116   }
 117   wakeup(&p->nwrite);  //DOC: piperead-wakeup
 118   release(&p->lock);
 119   return i;
 120 }

/* [<][>][^][v][top][bottom][index][help] */