Xv6 with picoc & Linkage editor  v1.0
The project delineate mutual cohesion between c library, linkage editor ( linker), interpreter and operating system by porting the same on xv6 kernel
pipe.c
00001 #include "types.h"
00002 #include "defs.h"
00003 #include "param.h"
00004 #include "mmu.h"
00005 #include "proc.h"
00006 #include "fs.h"
00007 #include "file.h"
00008 #include "spinlock.h"
00009 
00010 #define PIPESIZE 512
00011 
00012 struct pipe {
00013   struct spinlock lock;
00014   char data[PIPESIZE];
00015   uint nread;     // number of bytes read
00016   uint nwrite;    // number of bytes written
00017   int readopen;   // read fd is still open
00018   int writeopen;  // write fd is still open
00019 };
00020 
00021 int
00022 pipealloc(struct file **f0, struct file **f1)
00023 {
00024   struct pipe *p;
00025 
00026   p = 0;
00027   *f0 = *f1 = 0;
00028   if((*f0 = filealloc()) == 0 || (*f1 = filealloc()) == 0)
00029     goto bad;
00030   if((p = (struct pipe*)kalloc()) == 0)
00031     goto bad;
00032   p->readopen = 1;
00033   p->writeopen = 1;
00034   p->nwrite = 0;
00035   p->nread = 0;
00036   initlock(&p->lock, "pipe");
00037   (*f0)->type = FD_PIPE;
00038   (*f0)->readable = 1;
00039   (*f0)->writable = 0;
00040   (*f0)->pipe = p;
00041   (*f1)->type = FD_PIPE;
00042   (*f1)->readable = 0;
00043   (*f1)->writable = 1;
00044   (*f1)->pipe = p;
00045   return 0;
00046 
00047 //PAGEBREAK: 20
00048  bad:
00049   if(p)
00050     kfree((char*)p);
00051   if(*f0)
00052     fileclose(*f0);
00053   if(*f1)
00054     fileclose(*f1);
00055   return -1;
00056 }
00057 
00058 void
00059 pipeclose(struct pipe *p, int writable)
00060 {
00061   acquire(&p->lock);
00062   if(writable){
00063     p->writeopen = 0;
00064     wakeup(&p->nread);
00065   } else {
00066     p->readopen = 0;
00067     wakeup(&p->nwrite);
00068   }
00069   if(p->readopen == 0 && p->writeopen == 0){
00070     release(&p->lock);
00071     kfree((char*)p);
00072   } else
00073     release(&p->lock);
00074 }
00075 
00076 //PAGEBREAK: 40
00077 int
00078 pipewrite(struct pipe *p, char *addr, int n)
00079 {
00080   int i;
00081 
00082   acquire(&p->lock);
00083   for(i = 0; i < n; i++){
00084     while(p->nwrite == p->nread + PIPESIZE){  //DOC: pipewrite-full
00085       if(p->readopen == 0 || proc->killed){
00086         release(&p->lock);
00087         return -1;
00088       }
00089       wakeup(&p->nread);
00090       sleep(&p->nwrite, &p->lock);  //DOC: pipewrite-sleep
00091     }
00092     p->data[p->nwrite++ % PIPESIZE] = addr[i];
00093   }
00094   wakeup(&p->nread);  //DOC: pipewrite-wakeup1
00095   release(&p->lock);
00096   return n;
00097 }
00098 
00099 int
00100 piperead(struct pipe *p, char *addr, int n)
00101 {
00102   int i;
00103 
00104   acquire(&p->lock);
00105   while(p->nread == p->nwrite && p->writeopen){  //DOC: pipe-empty
00106     if(proc->killed){
00107       release(&p->lock);
00108       return -1;
00109     }
00110     sleep(&p->nread, &p->lock); //DOC: piperead-sleep
00111   }
00112   for(i = 0; i < n; i++){  //DOC: piperead-copy
00113     if(p->nread == p->nwrite)
00114       break;
00115     addr[i] = p->data[p->nread++ % PIPESIZE];
00116   }
00117   wakeup(&p->nwrite);  //DOC: piperead-wakeup
00118   release(&p->lock);
00119   return i;
00120 }
 All Data Structures