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 { 12c41f1de5Srtm int readopen; // read fd is still open 13c41f1de5Srtm int writeopen; // write fd is still open 14c41f1de5Srtm int writep; // next index to write 15c41f1de5Srtm int readp; // next index to read 164e8f237bSrtm struct spinlock lock; 17c41f1de5Srtm char data[PIPESIZE]; 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; 338b4e2a08Srtm p->writep = 0; 348b4e2a08Srtm p->readp = 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 46*6eed1ee9Srsc //PAGEBREAK: 20 473ce16470Srsc bad: 48c41f1de5Srtm if(p) 49c41f1de5Srtm kfree((char*)p, PAGE); 502cbb4b18Srsc if(*f0){ 512cbb4b18Srsc (*f0)->type = FD_NONE; 522cbb4b18Srsc fileclose(*f0); 53c41f1de5Srtm } 542cbb4b18Srsc if(*f1){ 552cbb4b18Srsc (*f1)->type = FD_NONE; 562cbb4b18Srsc fileclose(*f1); 57c41f1de5Srtm } 58c41f1de5Srtm return -1; 59c41f1de5Srtm } 60c41f1de5Srtm 61c41f1de5Srtm void 627834cca6Srsc pipeclose(struct pipe *p, int writable) 63c41f1de5Srtm { 64bd228a81Srtm acquire(&p->lock); 65d4c64e5dSrsc if(writable){ 66c41f1de5Srtm p->writeopen = 0; 678b4e2a08Srtm wakeup(&p->readp); 688b4e2a08Srtm } else { 69c41f1de5Srtm p->readopen = 0; 708b4e2a08Srtm wakeup(&p->writep); 718b4e2a08Srtm } 72bd228a81Srtm release(&p->lock); 73bd228a81Srtm 74c41f1de5Srtm if(p->readopen == 0 && p->writeopen == 0) 75c41f1de5Srtm kfree((char*)p, PAGE); 76c41f1de5Srtm } 77c41f1de5Srtm 78*6eed1ee9Srsc //PAGEBREAK: 30 79c41f1de5Srtm int 807834cca6Srsc pipewrite(struct pipe *p, char *addr, int n) 81c41f1de5Srtm { 82c41f1de5Srtm int i; 83c41f1de5Srtm 844e8f237bSrtm acquire(&p->lock); 85c41f1de5Srtm for(i = 0; i < n; i++){ 86c41f1de5Srtm while(((p->writep + 1) % PIPESIZE) == p->readp){ 87b6095304Srsc if(p->readopen == 0 || cp->killed){ 884e8f237bSrtm release(&p->lock); 8946bbd72fSrtm return -1; 9046bbd72fSrtm } 918b4e2a08Srtm wakeup(&p->readp); 9246bbd72fSrtm sleep(&p->writep, &p->lock); 93c41f1de5Srtm } 94c41f1de5Srtm p->data[p->writep] = addr[i]; 95c41f1de5Srtm p->writep = (p->writep + 1) % PIPESIZE; 96c41f1de5Srtm } 978b4e2a08Srtm wakeup(&p->readp); 98ea6e3709Srsc release(&p->lock); 99c41f1de5Srtm return i; 100c41f1de5Srtm } 101c41f1de5Srtm 102c41f1de5Srtm int 1037834cca6Srsc piperead(struct pipe *p, char *addr, int n) 104c41f1de5Srtm { 105c41f1de5Srtm int i; 106c41f1de5Srtm 10746bbd72fSrtm acquire(&p->lock); 1083ce16470Srsc while(p->readp == p->writep && p->writeopen){ 1093ce16470Srsc if(cp->killed){ 11046bbd72fSrtm release(&p->lock); 1113ce16470Srsc return -1; 11246bbd72fSrtm } 11346bbd72fSrtm sleep(&p->readp, &p->lock); 114c41f1de5Srtm } 115c41f1de5Srtm for(i = 0; i < n; i++){ 116c41f1de5Srtm if(p->readp == p->writep) 117c41f1de5Srtm break; 118c41f1de5Srtm addr[i] = p->data[p->readp]; 119c41f1de5Srtm p->readp = (p->readp + 1) % PIPESIZE; 120c41f1de5Srtm } 1218b4e2a08Srtm wakeup(&p->writep); 122ea6e3709Srsc release(&p->lock); 123c41f1de5Srtm return i; 124c41f1de5Srtm } 125