comparison source/pipe.c @ 0:c450faca55f4

Init
author Tatsuki IHA <innparusu@cr.ie.u-ryukyu.ac.jp>
date Sun, 22 Oct 2017 18:25:39 +0900
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:c450faca55f4
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 memset(p, 0, PGSIZE);
33 p->readopen = 1;
34 p->writeopen = 1;
35 p->nwrite = 0;
36 p->nread = 0;
37 initlock(&p->lock, "pipe");
38 (*f0)->type = FD_PIPE;
39 (*f0)->readable = 1;
40 (*f0)->writable = 0;
41 (*f0)->pipe = p;
42 (*f1)->type = FD_PIPE;
43 (*f1)->readable = 0;
44 (*f1)->writable = 1;
45 (*f1)->pipe = p;
46 return 0;
47
48 //PAGEBREAK: 20
49 bad:
50 if(p)
51 kfree((char*)p);
52 if(*f0)
53 fileclose(*f0);
54 if(*f1)
55 fileclose(*f1);
56 return -1;
57 }
58
59 void
60 pipeclose(struct pipe *p, int writable)
61 {
62 acquire(&p->lock);
63 if(writable){
64 p->writeopen = 0;
65 wakeup(&p->nread);
66 } else {
67 p->readopen = 0;
68 wakeup(&p->nwrite);
69 }
70 if(p->readopen == 0 && p->writeopen == 0){
71 release(&p->lock);
72 kfree((char*)p);
73 } else
74 release(&p->lock);
75 }
76
77 //PAGEBREAK: 40
78 int
79 pipewrite(struct pipe *p, char *addr, int n)
80 {
81 int i;
82
83 acquire(&p->lock);
84 for(i = 0; i < n; i++){
85 while(p->nwrite == p->nread + PIPESIZE){ //DOC: pipewrite-full
86 if(p->readopen == 0 || curr_proc->killed){
87 release(&p->lock);
88 return -1;
89 }
90 wakeup(&p->nread);
91 sleep(&p->nwrite, &p->lock); //DOC: pipewrite-sleep
92 }
93 p->data[p->nwrite++ % PIPESIZE] = addr[i];
94 }
95 wakeup(&p->nread); //DOC: pipewrite-wakeup1
96 release(&p->lock);
97 return n;
98 }
99
100 int
101 piperead(struct pipe *p, char *addr, int n)
102 {
103 int i;
104
105 acquire(&p->lock);
106 while(p->nread == p->nwrite && p->writeopen){ //DOC: pipe-empty
107 if(curr_proc->killed){
108 release(&p->lock);
109 return -1;
110 }
111 sleep(&p->nread, &p->lock); //DOC: piperead-sleep
112 }
113 for(i = 0; i < n; i++){ //DOC: piperead-copy
114 if(p->nread == p->nwrite)
115 break;
116 addr[i] = p->data[p->nread++ % PIPESIZE];
117 }
118 wakeup(&p->nwrite); //DOC: piperead-wakeup
119 release(&p->lock);
120 return i;
121 }