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
|
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 }