1c41f1de5Srtm #include "types.h" 2558ab49fSrsc #include "defs.h" 3c41f1de5Srtm #include "param.h" 4c41f1de5Srtm #include "mmu.h" 5c41f1de5Srtm #include "proc.h" 69936bffaSrsc #include "file.h" 74e8f237bSrtm #include "spinlock.h" 8c41f1de5Srtm 9c41f1de5Srtm #define PIPESIZE 512 10c41f1de5Srtm 11c41f1de5Srtm struct pipe { 124e8f237bSrtm struct spinlock lock; 13c41f1de5Srtm char data[PIPESIZE]; 14*00e57115SRuss Cox uint nread; // number of bytes read 15*00e57115SRuss Cox uint nwrite; // number of bytes written 16*00e57115SRuss Cox int readopen; // read fd is still open 17*00e57115SRuss Cox int writeopen; // write fd is still open 18c41f1de5Srtm }; 19c41f1de5Srtm 20c41f1de5Srtm int 217834cca6Srsc pipealloc(struct file **f0, struct file **f1) 22c41f1de5Srtm { 233bbbaca1Srsc struct pipe *p; 24c41f1de5Srtm 253bbbaca1Srsc p = 0; 263bbbaca1Srsc *f0 = *f1 = 0; 273ce16470Srsc if((*f0 = filealloc()) == 0 || (*f1 = filealloc()) == 0) 283ce16470Srsc goto bad; 29c41f1de5Srtm if((p = (struct pipe*)kalloc(PAGE)) == 0) 303ce16470Srsc goto bad; 318b4e2a08Srtm p->readopen = 1; 328b4e2a08Srtm p->writeopen = 1; 33*00e57115SRuss Cox p->nwrite = 0; 34*00e57115SRuss Cox p->nread = 0; 355be0039cSrtm initlock(&p->lock, "pipe"); 362cbb4b18Srsc (*f0)->type = FD_PIPE; 372cbb4b18Srsc (*f0)->readable = 1; 382cbb4b18Srsc (*f0)->writable = 0; 392cbb4b18Srsc (*f0)->pipe = p; 402cbb4b18Srsc (*f1)->type = FD_PIPE; 412cbb4b18Srsc (*f1)->readable = 0; 422cbb4b18Srsc (*f1)->writable = 1; 432cbb4b18Srsc (*f1)->pipe = p; 44c41f1de5Srtm return 0; 45f1f8dd91Srsc 466eed1ee9Srsc //PAGEBREAK: 20 473ce16470Srsc bad: 48c41f1de5Srtm if(p) 49c41f1de5Srtm kfree((char*)p, PAGE); 50f3685aa3Srsc if(*f0) 512cbb4b18Srsc fileclose(*f0); 52f3685aa3Srsc if(*f1) 532cbb4b18Srsc fileclose(*f1); 54c41f1de5Srtm return -1; 55c41f1de5Srtm } 56c41f1de5Srtm 57c41f1de5Srtm void 587834cca6Srsc pipeclose(struct pipe *p, int writable) 59c41f1de5Srtm { 60bd228a81Srtm acquire(&p->lock); 61d4c64e5dSrsc if(writable){ 62c41f1de5Srtm p->writeopen = 0; 63*00e57115SRuss Cox wakeup(&p->nread); 648b4e2a08Srtm } else { 65c41f1de5Srtm p->readopen = 0; 66*00e57115SRuss Cox wakeup(&p->nwrite); 678b4e2a08Srtm } 68e670a483Skolya if(p->readopen == 0 && p->writeopen == 0) { 69bd228a81Srtm release(&p->lock); 70c41f1de5Srtm kfree((char*)p, PAGE); 71e670a483Skolya } else 72e670a483Skolya release(&p->lock); 73c41f1de5Srtm } 74c41f1de5Srtm 756eed1ee9Srsc //PAGEBREAK: 30 76c41f1de5Srtm int 777834cca6Srsc pipewrite(struct pipe *p, char *addr, int n) 78c41f1de5Srtm { 79c41f1de5Srtm int i; 80c41f1de5Srtm 814e8f237bSrtm acquire(&p->lock); 82c41f1de5Srtm for(i = 0; i < n; i++){ 83*00e57115SRuss Cox while(p->nwrite == p->nread + PIPESIZE) { //DOC: pipewrite-full 84b6095304Srsc if(p->readopen == 0 || cp->killed){ 854e8f237bSrtm release(&p->lock); 8646bbd72fSrtm return -1; 8746bbd72fSrtm } 88*00e57115SRuss Cox wakeup(&p->nread); 89*00e57115SRuss Cox sleep(&p->nwrite, &p->lock); //DOC: pipewrite-sleep 90c41f1de5Srtm } 91*00e57115SRuss Cox p->data[p->nwrite++ % PIPESIZE] = addr[i]; 92c41f1de5Srtm } 93*00e57115SRuss Cox wakeup(&p->nread); //DOC: pipewrite-wakeup1 94ea6e3709Srsc release(&p->lock); 95*00e57115SRuss Cox return n; 96c41f1de5Srtm } 97c41f1de5Srtm 98c41f1de5Srtm int 997834cca6Srsc piperead(struct pipe *p, char *addr, int n) 100c41f1de5Srtm { 101c41f1de5Srtm int i; 102c41f1de5Srtm 10346bbd72fSrtm acquire(&p->lock); 104*00e57115SRuss Cox while(p->nread == p->nwrite && p->writeopen){ //DOC: pipe-empty 1053ce16470Srsc if(cp->killed){ 10646bbd72fSrtm release(&p->lock); 1073ce16470Srsc return -1; 10846bbd72fSrtm } 109*00e57115SRuss Cox sleep(&p->nread, &p->lock); //DOC: piperead-sleep 110c41f1de5Srtm } 111*00e57115SRuss Cox for(i = 0; i < n; i++){ //DOC: piperead-copy 112*00e57115SRuss Cox if(p->nread == p->nwrite) 113c41f1de5Srtm break; 114*00e57115SRuss Cox addr[i] = p->data[p->nread++ % PIPESIZE]; 115c41f1de5Srtm } 116*00e57115SRuss Cox wakeup(&p->nwrite); //DOC: piperead-wakeup 117ea6e3709Srsc release(&p->lock); 118c41f1de5Srtm return i; 119c41f1de5Srtm } 120